I'm having trouble with C++ classes and inheritance right now...
Let's say we have
Class A {
A(string name);
~A();
void func(void);
}
Class B : public A {
B(string name);
~B();
...
}
Class C : public A {
C(string name);
~C();
...
}
Class D : public B, public D {
D(string name);
~D();
...
}
Whenever I create D, it calls the constructor for B and the one for C which results in multiple instances of A. The compiler then says it doesn't know which "func" it should call, the one from B or the one from C.
I would like to know how to call A constructor ONLY ONCE and then use it to build B and C.
I already tried using B::func() to be able to call func() but has I must have a cout in the class A builder. It results in wrong output.
This is called the diamond inheritance pattern.
In order to avoid having 2 instances of A in D, you need to use virtual inheritance.
When classes e.g. B virtually inherit A, it means that A will be present only once in a class derived from those classes.
Note: in this case it is the responsibility of the most derived class to initialize the virtual base(s) - as shown below.
The output from the following code demonstrates it:
#include <iostream>
#include <string>
class A {
public:
A(std::string const & name) { std::cout << "A::A\n"; };
~A() {};
void func(void);
};
//--------vvvvvvv-----------
class B : virtual public A {
public:
B(std::string const& name) : A(name) { std::cout << "B::B\n"; };
~B() {};
};
//--------vvvvvvv-----------
class C : virtual public A {
public:
C(std::string const& name) : A(name) { std::cout << "C::C\n"; };
~C() {};
};
class D : public B, public C {
public:
//-------------------------------vvvvvvv---------------------------------------------
D(std::string const& name) : A(name), B(name), C(name) { std::cout << "D::D\n"; };
~D() {};
};
int main()
{
D d("aaa");
}
Output:
A::A
B::B
C::C
D::D
I.e. A is present once in D.
Note that if you remove the virtual keyword, the output will be:
A::A
B::B
A::A
C::C
D::D
I.e. A is present twice in D (as you observed).
Some side notes:
using namespace std - see here Why is "using namespace std;" considered bad practice?.Class should be class, missing ; at the end of classes.name by const & as demonstrated in my code, to avoid copy.