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.
CodePudding user response:
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:
- Better to avoid
using namespace std
- see here Why is "using namespace std;" considered bad practice?. - Your code contains many typos:
Class
should beclass
, missing;
at the end of classes. - You constructors can accept the
name
byconst &
as demonstrated in my code, to avoid copy.