I have a class A, needing a pointer to AA to work, required by the constructor. I have a class B inherited from A, providing to A a class BB inherited from AA. Example :
class A
{
public:
class AA
{
virtual void do_something() const;
};
protected:
const AA* aa;
public:
A(const A::AA* aa_) : aa(aa_) {}
void use() const { this->aa->do_something(); }
};
class B : public A
{
public:
class BB : public A::AA
{
virtual void do_something() const;
};
public:
B() : A(new BB()) {}
};
Now, I would like to give the address of the B instance to the BB instance. Somthing like that :
class B : public A
{
public:
class BB : public A::AA
{
BB(B* b);
virtual void do_something() const;
};
public:
B() : A(new BB(this)) {}
// It doesn't work beacause the instance is not yet created
};
Or something like that :
class B : public A
{
public:
class BB : public A::AA
{
virtual void do_something() const;
void setPointer(B* b);
};
public:
B() : A(new BB()) { static_cast<BB*>(this->aa)->setPointer(this); }
// It doesn't work because this->aa is const
};
How can I do that ? Is there a design pattern solving this kind of problem ?
If you only want BB:BB to store the pointer, then
B() : A(new BB(this)) {}
should work just fine.
If you want it to use the pointer, then your best bet is to store the pointer in the constructor, and use it in a second function like this:
B() : A(new BB(this)) { static_cast<const BB*>(this->aa)->UseStoredThis();
That assumes you can mark UseStoredThis as const. If not, then you will need:
B() : A(new BB(this))
{
const auto pcBB = static_cast<const BB*>(this->aa);
const auto pBB = const_cast<BB*>(pcBB);
pBB->UseStoredThis();
}
Making AA::do_something public or protected and BB's constructor public, makes your code compilable.
Refactoring a little you can get a nice version as well:
class A {
public:
struct AA {
virtual void do_something() const;
};
A(A::AA const* aa_) : aa(aa_) {}
void use() const { this->aa->do_something(); }
protected:
AA const* aa;
};
struct B : public A {
struct BB : public A::AA {
BB(B* b) {}
virtual void do_something() const override;
};
B() : A(new BB(this)) {}
};
Live demo
Related
How to convert two parent pointers in c++?
This is the code.
// base class
class B {
public:
virtual ~B() {};
// other code
};
class A {
public:
virtual ~A() {};
// other code
};
// child class
class C1 : public A, B {
public:
virtual ~C1() {};
// other code
};
class C2 : public A, B {
public:
virtual ~C2() {};
// other code
};
// ...other C class
There is a std::vector<std::shared_ptr<A>> which items point to instance C1 or C2 ...Cn.
Does anyone know how to convert the vector to a std::vector<std::shared_ptr<B>>?
Your code has typos. Missing public in inheritance of B when defining C<x> breaks stuff.
After this is fixed sidecast does the job as it should:
dynamic_cast conversion - cppreference.com
b) Otherwise, if expression points/refers to a public base of the most derived object, and, simultaneously, the most derived object has an unambiguous public base class of type Derived, the result of the cast points/refers to that Derived (This is known as a "sidecast".)
// base class
class B {
public:
virtual ~B() { }
};
class A {
public:
virtual ~A() { }
};
class C1 : public A, public B {
public:
virtual ~C1() { }
};
class C2 : public A, public B {
public:
virtual ~C2() { }
};
TEST(SideCast, sigleItemCast)
{
C2 x;
A* a = &x;
auto b = dynamic_cast<B*>(a);
ASSERT_THAT(b, testing::NotNull());
}
TEST(SideCast, sideCastOfVectorContent)
{
std::vector<std::shared_ptr<A>> v { std::make_shared<C1>(), std::make_shared<C2>() };
std::vector<std::shared_ptr<B>> x;
std::transform(v.begin(), v.end(), std::back_inserter(x),
[](auto p) { return std::dynamic_pointer_cast<B>(p); });
ASSERT_THAT(x, testing::Each(testing::NotNull()));
}
Live demo
I apologize if my question is dumb but i'm a beginner in c++. I'm working on diamond inheritance and i would like to know if it is possible to choose the specific parent class which will initilize an attribute for the child class.
To sum up, i would like this code to output B
Thank you for your answers !
PS: i'm working with c++98
#include <iostream>
class A
{
protected:
char m_char;
public:
A(): m_char('A'){};
char getChar(){return m_char;};
~A(){};
};
class B : virtual public A
{
private:
public:
B() {m_char = 'B';};
~B(){};
};
class C : virtual public A
{
private:
public:
C() {m_char = 'C';};
~C(){};
};
class D : public B, public C
{
private:
public:
D() {m_char = B::m_char;};
~D(){};
};
int main(void)
{
D d;
std::cout << d.getChar() << std::endl;
}
Virtual base classes are initialized In depth-first, left-to-right order. So you would need to name B second in your inheritance for D to call its constructor last and thus setting the variable to B at the end.
class D : public C, public B
m_char = B::m_char; is self assignment (there is only one m_char).
In virtual inheritance, it is the most derived class which initialize the virtual class (body does assignment).
How about being explicit in construction:
#include <iostream>
class A
{
protected:
char m_char;
public:
A() : m_char('A') {}
char getChar() const { return m_char; }
virtual ~A() {}
};
class B : virtual public A
{
public:
B() : A('B') {}
};
class C : virtual public A
{
public:
C() : A('C') {}
};
class D : public B, public C
{
public:
D() : A('B'), B(), C() {}
};
int main()
{
D d;
std::cout << d.getChar() << std::endl;
}
This is a simple question (I think). I'm just not sure about it and I'm looking for a good solution too :)
Let's say I have this:
class Base {
public:
virtual ~Base() {}
virtual Base& connect(Base &b) = 0;
}
class Derived: public Base {
public:
virtual ~Derived() {}
virtual Base& connect(Base &b)
{
// do_something
}
}
// Name is a class that is basically a String and assign it to any A or B object.
class A: public Derived {
public:
A(name N) { ... }
virtual ~A() {}
}
class B: public Derived {
public:
B(name N) { ... }
virtual ~B() {}
A& connect(A &a)
{
// do something else
}
}
int main(int argc, char *argv[])
{
A objA("A");
B objB("B");
// Here's where is my issue
objB.connect(objA);
}
When I call objB.connect(objA), it is actually calling Base& connect(Base &b). I understand because both are child of Base and both have connect() defined in Derived. But the thing is that I would like that whenever I have objB.connect(objA), it should call A& connect(A &a) instead.
I would like to know if there is a way to have it the way I want.
Thanks :)
UPDATE
I edited this, because I had several typos. I didn't copy-paste the code, because it is quite more complex than I wish >.< Hope it is enough.
Your code won't compile. Here is code that compiles and result is as you desire: you can choose which version of connect to call based on a pointer type:
class Base {
public:
virtual ~Base() {}
virtual Base& connect(Base &b) = 0;
};
class Derived: public Base {
public:
virtual ~Derived() {}
virtual Base& connect(Base &b)
{
qDebug() << "Baseconnect";
}
};
class AA: public Derived {
public:
AA() {}
virtual ~AA() {}
};
class BB: public Derived {
public:
BB() {}
virtual ~BB() {}
AA& connect(AA &a)
{
qDebug() << "Aconnect";
}
};
example:
int main(int argc, char *argv[])
{
AA* aaptr = new AA;
BB* bbptr = new BB;
bbptr->connect(*aaptr); // version from BB is called
Derived* dptr = new BB;
dptr->connect(*aaptr); // version from Derived is called
// ...
}
As a side note, please always ensure that your code compiles and question is well defined. You narrow down the chances for helpful answer to your question otherwise.
class IA
{
public:
virtual void a() = 0;
};
class A: public IA
{
public:
virtual void a()
{
}
};
class IB
{
public:
virtual void b() = 0;
};
class B: public IB, public A
{
public:
virtual void b()
{
}
};
void f(IA* p)
{
}
int main()
{
B b = B();
IB* p = &b;
f(p);
}
Is this the correct way to implement interfaces with inheritance in C++? If so, how do I get the line f(p); in my code to compile? Basically, I would like if IB could inherit from IA but this will cause problems for B.
UPDATE
What I want is for IB to include IA's interface, as follows. However this code wont compile since IA::a() and A::a() conflict with each other. What should I do?
class IA
{
public:
virtual void a() = 0;
};
class A: public IA
{
public:
virtual void a()
{
}
};
class IB : public IA
{
public:
virtual void b() = 0;
};
class B: public IB, public A
{
public:
virtual void b()
{
}
};
UPDATE 2
This compiles, does it look correct? Do I need all these virtuals
class IA
{
public:
virtual void a() = 0;
};
class A: virtual public IA
{
public:
virtual void a()
{
}
};
class IB: virtual public IA
{
public:
virtual void b() = 0;
};
class B: virtual public IB, public A
{
public:
virtual void b()
{
}
};
Well, this is the right way of course, but the line f(p) should not compile as is, imagine classes that implement IB, but don't implement IA, it's possible, so you cannot assume that they all implement IA. If you want to assume that, you can inherit IB from IA, but this is another design. It can be implemented like this:
class IA
{
public:
virtual void a() = 0;
};
class A: virtual public IA
{
public:
virtual void a()
{
}
};
class IB : virtual public IA
{
public:
virtual void b() = 0;
};
class B: public IB, public A
{
public:
virtual void b()
{
}
};
Here is my issue. I want to have something like this:
class A {
protected:
int someInt;
virtual void someFunc() = 0;
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B() {//tell the A inside of B to set someInt to whatever it wants}
};
so basically, someInt can be changed, it's not constant, but I want all the classes that implement A to use a value provided by A for someInt.
Thanks
You can use initializer lists in the constructor to call parent constructors:
class A {
protected:
int someInt;
virtual void someFunc() = 0;
A(int x) : someInt(x) {} // Base-class constructor (initialises someInt)
};
class B : public A {
protected:
virtual void someFunc() {}
public:
B() : A(10) {} // Initialises base class via constructor
};
Is this what you want?
class A
{
protected:
int someInt;
public:
A(int _val) : someInt(_val)
{
}; // eo ctor
}; // eo class A
class B : public A
{
public:
B() : A(5) // initialise someInt with 5
{
}; // eo ctor
}; // eo class B
Note, that as "someInt" is protected, you can just set it in B's constructor anyway.
B()
{
A::someInt = 5;
}; // eo ctor
I am not sure what you want, but if you initialize someInt in the constructor of A, subclasses will see that value.
class A {
public:
A() : someInt(5) {}
protected:
int someInt;
virtual void someFunc() = 0;
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B() {// at this point someInt will already have been initialized to 5}
};
When the subclass is constructed, the baseclass constructors are executed first.
class A {
protected:
int someInt;
virtual void someFunc() = 0;
A(){//set someInt here}
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B():A() {}
};
A protected constructor will achieve this. As above. The solutions using a public constructor are fine too, but as the constructor cannot be called directly on thr interface I think protected is better.