C++ copy constructor in inheritance
Asked Answered
T

1

8
#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):A(obj){cout<<"4";}
};

class C: virtual A
{
public:
   C(){cout<<"5";}
   C(const C & obj):A(obj){cout <<"6";}
};

class D:B,C
{
public:
    D(){cout<<"7";}
    D(const D & obj):C(obj),B(obj){cout <<"8";}
};

int main()
{
   D d1;
   D d(d1);
}

I am getting 13571468 as output. But I think that output should be 13572468. Why normal constructor is running instead on of copy constructor of class A?

Trichite answered 4/8, 2018 at 14:39 Comment(5)
Just provide a virtual ~A() destructor.Drynurse
Possible duplicate of What is a debugger and how can it help me diagnose problems?Eidetic
Hmm, I doubt that's really can be considered a dupe of that.Drynurse
tpcg.io/oOKrrf This is the link to the problem,Please edit it and share a link of the modified program.Trichite
It took me a while to notice that it's using virtual inheritance. Very interesting questionWhippletree
P
12

Your code makes a copy of an instance of D, invoking its copy constructor.

Your class D's copy constructor only invokes the copy constructors of its C and B's superclasses. Because it does not invoke A's copy constructor, it gets default-constructed.

Virtually-inherited classes can be thought of as direct superclasses of the most-derived class. That's what virtual inheritance means. As such, in your instance of D, its virtually-inherited A is a direct superclass of D, and not of B or C; as such, B and C's invocations of A copy-constructor is not invoked.

When you have a virtually-inherited class, all your constructors really have two versions created "behind the scenes": one that's responsible for constructing any virtually-inherited classes, and one that's not. The one that's not does not call the virtually-inherited classes's constructors.

Preprandial answered 4/8, 2018 at 14:49 Comment(8)
Why doesn't C's copy c'tor invoke A's copy c'tor?Milkman
Because it is not responsible for doing so. Only the most-derived class constructs all virtually-inherited superclasses. I amended my answer to explain this. If you copy-construct C, it will do it. But if you copy-construct D, it doesn't do that. D is responsible for constructing A.Preprandial
It might be helpful to go into more detail about the fact that there are two copy constructors for C - and.Bezel
If I do this D(const D & obj):C(obj),B(obj),A(obj){cout <<"8";} , then it is giving error. Can you please tell a way to call the base class i.e. A's copy contructor.Trichite
You have to explicitly declare D as virtually inheriting from A, like all other classes. Then you can invoke its copy constructor. If you don't declare it, it still virtually inherits A, of course. But it always uses its default constructor.Preprandial
Thanks a lot @SamVarshavchikTrichite
@SamVarshavchik "You have to explicitly declare D as virtually inheriting from A" what do you mean?Coursing
Why, class D:B,C,virtual A { /* with the rest being the same */ of course -- and I'm just curious what would've been more clear to you than "You have to explicitly declare D as virtually inheriting from A, like all other classes".Preprandial

© 2022 - 2024 — McMap. All rights reserved.