问题
Possible Duplicate:
gcc c++ virtual inheritance problem
Hi all,
I'm wondering about how the compiler would handle different initialization values when using multiple inheritance from a virtual base class. Consider the notorious 'diamond of dread' inheritance scheme:
Base
/ \
/ \
D1 D2
\ /
\ /
Join
In order to avoid having two copies of Base
in Join
, I use virtual inheritance for D1
and D2
(see e.g. here). Now, lets say Base
is not abstract, but has a member field, which is initialized in its constructor:
class Base {
public:
Base(int x_) {x = x_;};
virtual ~Base(){};
public:
int x;
};
class D1 : public virtual Base {
public:
D1() : Base(1) {};
virtual ~D1(){};
};
class D2 : public virtual Base {
public:
D2() : Base(2) {};
virtual ~D2(){};
};
class Join : public D1, public D2 {
public:
Join(){};
~Join(){};
};
int main()
{
Join j;
cout << j.x << endl;
return 0;
}
Will the output be 1, 2, or is it compiler-dependent?
回答1:
It shoudn't compile. Virtual bases are initialized by the most derived class which is Join
. Join
doesn't explicitly initialize Base
but Base
has no accessible default constructor.
[It also won't compiler because definitions of classes need to be terminated with a ;
but I've assumed that this is a typo. main
should also return int
and I've assumed that j.x
is a typo for j->x
.]
回答2:
When you have virtual inheritance it is the final class that must initialise the virtual base class.
Therefore the constructor of Join must construct Base:
class Join : public D1, public D2
{
public:
Join() : Base(3){} // or whatever value
~Join(){}
};
It is the exception to the rule that classes only normally initialise their immediate base-classes.
(Aside from that main
should return int
and you would need to do j->x
not j.x
as j is a pointer, as well as the fact you must delete
it as you called new
)
回答3:
Since the Base does not have an implicit constructor and both C1
and C2
are virtual bases, you would have to change it like this (and also add semicolons after the rest of the class declarations as pointed out by Charles Bailey)
class Join : public D1, public D2 {
public:
Join() : Base(3) {};
~Join(){};
};
int main()
{
Join j;
cout << j.x << endl;
}
Then it would print 3
to the standard output
来源:https://stackoverflow.com/questions/4849289/virtual-base-class-and-initialization-lists