Consider the below code:
#include<iostream>
using namespace std;
class A
{
public:
A() {cout << "1";}
A(const A &obj) {cout << "2";}
};
class B: virtual A
{
public:
B() {cout << "3";}
B(const B & obj) {cout<< "4";}
};
class C: virtual A
{
public:
C() {cout << "5";}
C(const C & obj) {cout << "6";}
};
class D:B,C
{
public:
D() {cout << "7";}
D(const D & obj) {cout << "8";}
};
int main()
{
D d1;
cout << "\n";
D d(d1);
}
The output of the program is below:
1357
1358
So, for line D d(d1)
the copy constructor of D
class is bein called. During inheritance we need to explicitly call copy constructor of base class otherwise only default constructor of base class is called. I understood till here.
My Problem:
Now I want to call copy constructor of all base classes during D d(d1)
execution. For that if I try below
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
Then I get this error:
error: 'class A A::A' is inaccessible within this context
How to resolve the issue. I want copy constructor of A
, B
and C
when copy constructor of D
gets called. It might be very small change but I am not getting.
Copy constructor is not inherited.
Whenever the derived class's default constructor is called, the base class's default constructor is called automatically. To call the parameterized constructor of base class inside the parameterized constructor of sub class, we have to mention it explicitly.
The Diamond Problem is fixed using virtual inheritance, in which the virtual keyword is used when parent classes inherit from a shared grandparent class. By doing so, only one copy of the grandparent class is made, and the object construction of the grandparent class is done by the child class.
To pass arguments to a constructor in a base class, use an expanded form of the derived class' constructor declaration, which passes arguments along to one or more base class constructors. Here, base1 through baseN are the names of the base classes inherited by the derived class.
First, lets change your inheritance as currently it is private:
class B : virtual protected A {...};
class C : virtual protected A {...};
Now, in your copy constructor, explicitly specify that the copy constructors of A
and B
and C
should be called:
class D : protected B, protected C {
D(const D & obj) : A(obj), B(obj), C(obj) {cout << "8";}
};
And the output will be as desired (2468
).
When we have virtual base classes, they must be initialized by the most derived class, otherwise there would be ambiguity concerning whether B
or C
for example is responsible for the construction of A
.
§12.6.2, (13.1):
In a non-delegating constructor, initialization proceeds in the following order:
- First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
In particular, if you define a copy constructor, and omit the list of copy constructors it should call, then the default constructors will be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With