Suppose the following class hierarchy : (If you don't know what virtual inheritance means read this).
class A { }; class B1 : public virtual A { }; class B2 : public virtual A { }; class C : public B1, public B2 { };
Now suppose A has a non-trivial constructor, for instance like this:
class A { public: A(int i) { /* ... */ } };
Because B1 and B2 may disagree on how A must be initialized, A must be initialized from C. This might look like this:
class C { C() : A(42) { } };
In my special case, B1 and B2 are meant to be used within the diamond only. But the compiler does not know this. It could be that another compilation unit defines a class which inherits from B1 without creating a diamond. In this case B1 must initialize A. So B1 needs to call A's constructor. This looks like this:
class A { public: A(int i) { /* ... */ } }; class B1 : public virtual A { public: B1() : A(0) { } }; class B2 : public virtual A { public: B2() : A(0) { } }; class C : public B1, public B2 { public: C() : A(42) { } };
Without going into much detail, in the case I encountered there is no meaningful value B1 or B2 could initialize A with. Not only that I have to define an initializer which is never called, I must find some I-don't-really-mean-it value to not initialize A with. What a mess.
Alternatively you could define a default constructor for A which is never called. Perhaps like this:
class A { A(int i) { /* ... */ } A() { assert(false); } };
which is not really better.
Well, what should I say, this is C++...
No comments:
Post a Comment