Help: virtual inheritance, non-default constructor

J

jeffc

When compiling the following program, I get an error on the line specified:
The base class "B" cannot be initialized because it does not have a default
constructor.

If I remove the "virtual" inheritance of B (so that it uses plain
inheritance), it compiles fine. It also compiles if I invoke the
constructor for B explicitly, as shown in the comment after the error. I'm
not aware of any reason that virtual inheritance should be special in this
respect. What's wrong?

class B
{
public:
B(int){}
};

class C : virtual public B
{
public:
C():B(1){}
};

class D : public C
{
public:
D(){} // error here
// D():B(1){} - this however compiles OK
};

int main()
{
return 0;
}
 
R

Ron Natalie

jeffc said:
When compiling the following program, I get an error on the line specified:
The base class "B" cannot be initialized because it does not have a default
constructor.
The initialization of a virtual base is done by the most derived object.
Your class D must provide the necessary initializers for the virtual base
B. The virtual base is initialized just once and before any of the non-virtual
bases are initialized.
 
J

jeffc

jeffc said:
When compiling the following program, I get an error on the line specified:
The base class "B" cannot be initialized because it does not have a default
constructor.

If I remove the "virtual" inheritance of B (so that it uses plain
inheritance), it compiles fine. It also compiles if I invoke the
constructor for B explicitly, as shown in the comment after the error. I'm
not aware of any reason that virtual inheritance should be special in this
respect. What's wrong?

I finally found a reference to this problem in "Effective C++". Meyers
states that "arguments are specified in the member initialization lists of
the classes *most derived* from the base. As a result, the class
initializing a virtual base may be arbitrarily far from it in the
inheritance graph, and furthermore, the class performing the initialization
can change as new classes are added to the hierarchy."

So, 3 questions:
1) why is this so?
2) is he implying that once a new class is added to the hierarchy, the
initialization must be performed there *instead of* in the base class?
(because this seems inconsistent with what happens in the code I posted -
both the derived class and base class initialize the virtual base.
3) why does this make any difference at all, since I'm not even using
multiple inheritance? Is it merely a compiler implementation issue?
 
L

lilburne

jeffc said:
I finally found a reference to this problem in "Effective C++". Meyers
states that "arguments are specified in the member initialization lists of
the classes *most derived* from the base. As a result, the class
initializing a virtual base may be arbitrarily far from it in the
inheritance graph, and furthermore, the class performing the initialization
can change as new classes are added to the hierarchy."

So, 3 questions:
1) why is this so?
2) is he implying that once a new class is added to the hierarchy, the
initialization must be performed there *instead of* in the base class?
(because this seems inconsistent with what happens in the code I posted -
both the derived class and base class initialize the virtual base.
3) why does this make any difference at all, since I'm not even using
multiple inheritance? Is it merely a compiler implementation issue?

IIRC in my copy of Meyer's he starts of with "Just when you
thought you understood it, they change the rules!" or some
such. A page onwards I believe he gives an explaination of why.
 
J

jeffc

lilburne said:
IIRC in my copy of Meyer's he starts of with "Just when you
thought you understood it, they change the rules!" or some
such. A page onwards I believe he gives an explaination of why.

He does say that - in the next subsection (which deals with virtual
functions). But I didn't see further explanation.
 
J

jeffc

Ron Natalie said:
The initialization of a virtual base is done by the most derived object.
Your class D must provide the necessary initializers for the virtual base
B. The virtual base is initialized just once and before any of the non-virtual
bases are initialized.

I'm having another problem (I get a link error when I define a constructor -
it says some symbol is defined more than once), but I can't narrow it down
enough to post it. Anyway, in our code, there is virtual inheritance of the
a class, but no multiple inheritance. Other than designing for the fact
that someone *might* use multiple inheritance, is there any reason to use
virtual inheritance?
 
R

Ron Natalie

jeffc said:
I'm having another problem (I get a link error when I define a constructor -
it says some symbol is defined more than once), but I can't narrow it down
enough to post it.

Do you have it not-inlined but still in the include file? That will cause the problem.
 
L

lilburne

jeffc said:
I'm having another problem (I get a link error when I define a constructor -
it says some symbol is defined more than once), but I can't narrow it down
enough to post it. Anyway, in our code, there is virtual inheritance of the
a class, but no multiple inheritance. Other than designing for the fact
that someone *might* use multiple inheritance, is there any reason to use
virtual inheritance?

Well you only 'need' virtual inheritance if you have
multiple inheritance of classes derived from a common base
and you only want one copy of the base. It brings with it a
whole host of complications, which you're probably best off
avoiding if at all possible. You'd be unwise to add it just
on the off-chance. Stuff will get complicated enough anyway
so why add to it needlessly?
 
J

jeffc

Ron Natalie said:
Do you have it not-inlined but still in the include file? That will
cause the problem.

Sorry, I said "constructor" but I meant to say "destructor". I do not have
anything defined in the include file. I realize it's not enough to go on,
but until and unless I can narrow down the problem, posting the code isn't
really an option.
 
J

jeffc

lilburne said:
Well you only 'need' virtual inheritance if you have
multiple inheritance of classes derived from a common base
and you only want one copy of the base. It brings with it a
whole host of complications, which you're probably best off
avoiding if at all possible. You'd be unwise to add it just
on the off-chance. Stuff will get complicated enough anyway
so why add to it needlessly?

Yes, well that is true. The problem is that it's already there in the code
I'm customizing, and I really don't know why.
 
L

lilburne

jeffc said:
Yes, well that is true. The problem is that it's already there in the code
I'm customizing, and I really don't know why.

Ask the class author, or check back through the classes
implementation history. What other classes inherit from it,
and how do they resolve the problems? Was the virtual really
intended or was someone just trying to impress? Perhaps you
can get permission to remove it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top