Copy Constructor not Called in Virtual Inheritance

I have the following classes and 'dreaded diamond':


   A
  / \
 /   \
B     C
 \   /
  \ /
   D
   |
   |
   E


Classes B & C both inherit from A using public virtual A.
E is the only concrete class. None of the classes are totally abstract.
Every class has a copy constructor.
All of the copy constructors are chained together through the initialization lists.
E correctly calls D's copy constructor.
D correctly calls B and C's copy constructors.
But neither B nor C call A's copy constructor, although A's default constructor is called. To reiterate B and C have a call to A's copy constructor in their initialization lists.

I guess A's default constructor is being called is because of virtual inheritence, but why isn't its copy constructor called (too)?
A's copy constructor includes some very important code and I could do with calling it. Should I call it from the concrete class' initialization list or is that considered bad form?
Last edited on
With virtual inheritance it is the responsibility of a class to call the correct constructor of all virtually inherited base classes from its own constructors. This has to happen to resolve the conflict of the possibility of B and C having different ctor calls to A.
Last edited on
Thanks for the explanation, but I'm a little confused by your solution.

Which class has the responsibility of calling the base class from its own constructors? B and C are currently fullfilling that responsibility, but I guess that is ambiguous and is why it doesn't work? So should class D (the class at the diamond point) or E (the last concrete class) have that responsibility? Or is the choice up to me?

Reg.
In your case, D virtually inherits A, so it is D's responsibility.

Just remember this: If class X inherits from class Y, and class Y inherits from class Z with the virtual keyword, then X must call Z's constructors.

For you, E just inherits D and since D doesn't extend any classes with the virtual keyword, E has no responsibilities.

Basically, you handle classes two levels up if those classes were inherited with the virtual keyword one level up. "virtual" inheritance means "let the next class to extend me handle it if I'm not the concrete one."


I was wrong, see: http://www.cplusplus.com/forum/general/98582/#msg529927
Last edited on
Thanks for your help. Nice and clear.
Sorry, spoke too soon...

Calling class A's copy constructor from class D's copy constructor's initialization list doesn't work. Class A's copy constructor is left uncalled.

Is the initialization list the correct place to call it from?
Calling it from the body doesn't work because A is abstract.
I've moved it to class E and that has worked.
I seem to remember once reading something about 'the most derived class' and virtual inheritance. Could that be it?
I was wrong, apparently all further classes in the chain are responsible for A.

http://ideone.com/pDVKKd

The most derived handles it, but all have to be responsible in case they are the ones instantiated.
Last edited on
Wow, talk about going the extra mile.
Most derived class it is.

Thanks.
Topic archived. No new replies allowed.