.NET Forum / Languages / Managed C++ / March 2005
virtual inheritance question
|
|
Thread rating:  |
Bruno van Dooren - 15 Mar 2005 12:10 GMT Hi all,
i am having a problems with inheritance. consider the following:
class A { public: A(int i){;} };
class B: virtual public A { public: B(int i) : A(i){;} };
class C: virtual public B { public: C(int i) : B(i){;} //raises error C2512: 'A::A' : no appropriate default constructor available };
can someone tell me why i get that error? it has to do with the fact that B has virtual inheritance from A. if i make that non-virtual, the error is gone. what is the impact of the 'virtual' keyword in this situation?
kind regards, Bruno.
Tom Widmer - 15 Mar 2005 12:36 GMT > Hi all, > [quoted text clipped - 23 lines] > has virtual inheritance from A. if i make that non-virtual, the error is > gone. what is the impact of the 'virtual' keyword in this situation? When you use virtual inheritence, you need to initialize each virtual base class in the most derived class constructor, since you might have multiple bases that would do the initialisation if this wasn't the case (e.g. the classic diamond virtual inheritance example). So your C class constructor needs to initialize the A base object as well as the B one - B's initialization of A is ignored when creating a C object.
Tom
Bruno van Dooren - 15 Mar 2005 13:37 GMT > (e.g. the classic diamond virtual inheritance example). So your C class > constructor needs to initialize the A base object as well as the B one - > B's initialization of A is ignored when creating a C object. > > Tom thanks. however, this has the followig implications: please consider a new scenario:
class A { public: A(int i){;} };
class B: virtual public A { public: B(int i) : A(i){;} };
class C: virtual public A { public: C(int i) : A(i){;} };
class D: virtual public B, C { public: D(int i): C(i),B(i),A(i){;} };
in this case i end up with C and B using the same instance of A. multiple inheritance is the only scenario in which i can see a use for virtual inheritance. looking at it like this, it seems that the only use of the 'virtual' keyword in inheritance context is to say "whoever inherits from me has to initialize my base class too"
this meaning seems unrelated to the meaning of virtual in the context of member functions. is that correct?
kind regards, Bruno.
Carl Daniel [VC++ MVP] - 15 Mar 2005 15:41 GMT >> (e.g. the classic diamond virtual inheritance example). So your C >> class constructor needs to initialize the A base object as well as [quoted text clipped - 31 lines] > multiple inheritance is the only scenario in which i can see a use for > virtual inheritance. I'd agree with that statement.
> looking at it like this, it seems that the only use of the 'virtual' > keyword in inheritance context is to say "whoever inherits from me > has to initialize my base class too" It does imply that, yes.
> this meaning seems unrelated to the meaning of virtual in the context > of member functions. is that correct? Mostly unrelated - they just re-used the keyword rather than coming up with yet another one. The way virtual base classes are implemented is not dissimilar to how virtual functions are implemented, however. Classes that have virtual bases have a virtual base table, just like they have a virtual function table. The entries in the virtual base table gives the offset from the start of the complete object to the corresponding virtual base.
-cd
adebaene@club-internet.fr - 15 Mar 2005 18:10 GMT > > this meaning seems unrelated to the meaning of virtual in the context > > of member functions. is that correct? > > Mostly unrelated - they just re-used the keyword rather than coming up with > yet another one. The way virtual base classes are implemented is not
> dissimilar to how virtual functions are implemented, however. Classes that > have virtual bases have a virtual base table, just like they have a virtual > function table. The entries in the virtual base table gives the offset from > the start of the complete object to the corresponding virtual base. Nonetheless, I find it was a mistake to reuse the same keyword for something completely different, even if the inner implementation guts may have some vague relation. One more time, the "do-not-add-a-new-keyword-for-any-reason-even-a-very-good-one" syndrom has bitten us!
Arnaud MVP -VC
Bruno van Dooren - 15 Mar 2005 19:17 GMT > Nonetheless, I find it was a mistake to reuse the same keyword for > something completely different, even if the inner implementation guts [quoted text clipped - 4 lines] > Arnaud > MVP -VC I had the same feeling, but not the audacity of venting this opinion on a public forum because i am obviously not a C++ guru or an MVP. I feel good knowing that i am not alone in this opinion.
we might as well throw every means of transportation on wheels out of the dictionary and call everything a bycicle: car == bycicle with 4 wheels and an engine. moto bike = bycicle with an engine train == bicyle with lots of wheels, a heavy duty engine, drives on a predefined track. ...
Vladimir Nesterovsky - 16 Mar 2005 13:44 GMT > > > this meaning seems unrelated to the meaning of virtual in the > context [quoted text clipped - 17 lines] > "do-not-add-a-new-keyword-for-any-reason-even-a-very-good-one" syndrom > has bitten us! In fact, a virtual base class relates to a base class the same way, as a virtual member function relates to a non-virtual member function.
You can override implementation of a virtual base class in the derived class. Often virtual base classes contain pure member functions only. These member functions are overriden in descendants. This way you are achieving a construction called interface.
 Signature Vladimir Nesterovsky e-mail: vladimir@nesterovsky-bros.com home: www.nesterovsky-bros.com
Carl Daniel [VC++ MVP] - 16 Mar 2005 15:39 GMT > In fact, a virtual base class relates to a base class the same way, > as a virtual member function relates to a non-virtual member function. > > You can override implementation of a virtual base class in the derived > class. Nonsense - there's no such thing as overriding a virutal base class.
> Often virtual base classes contain pure member functions only. > These member functions are overriden in descendants. In which case you're simply overriding virtual functions declared in the base class (which happens to be virtual). Any non-virtual members in the virtual base class are still there and cannot be overridden.
> This way you are achieving a construction called interface. Which you can do just fine without the use of virtual base classes (see COM, for example).
-cd
Vladimir Nesterovsky - 16 Mar 2005 17:18 GMT > > In fact, a virtual base class relates to a base class the same way, > > as a virtual member function relates to a non-virtual member function. [quoted text clipped - 3 lines] > > Nonsense - there's no such thing as overriding a virutal base class. struct A { virtual void f() { std::cout << "struct A" << std::endl; } virtual void f2() { std::cout << "struct A" << std::endl; } };
struct B: public virtual A { virtual void f() { std::cout << "struct B" << std::endl; } virtual void f2() { std::cout << "struct B" << std::endl; } };
struct C: public virtual A {};
struct D: public C, public virtual B {};
int main() { C &c1 = C(); C &c2 = D();
c1.f(); c2.f(); }
From these declarations we can see that ? contains A as its part, however B substitutes A in the D. In this sence B overrides A in the D, which is descendant of the C.
> > Often virtual base classes contain pure member functions only. > > These member functions are overriden in descendants. [quoted text clipped - 7 lines] > Which you can do just fine without the use of virtual base classes (see COM, > for example). In fact .NET interfaces are closer to a virtual pure base classes than to other model.
 Signature Vladimir Nesterovsky e-mail: vladimir@nesterovsky-bros.com home: www.nesterovsky-bros.com
Carl Daniel [VC++ MVP] - 16 Mar 2005 20:52 GMT >> > In fact, a virtual base class relates to a base class the same way, >> > as a virtual member function relates to a non-virtual member function. [quoted text clipped - 3 lines] >> >> Nonsense - there's no such thing as overriding a virutal base class. [snipped to save space]
> From these declarations we can see that ? contains A as its part, however > B > substitutes A in the D. > In this sence B overrides A in the D, which is descendant of the C. Not so. B overrides the functions originally declared in A, it does not override A itself. If your virtual base contains only pure virtual functions, there's no practical difference. It's when your virtual base contains data members that the distinction is important.
-cd
Vladimir Nesterovsky - 17 Mar 2005 10:00 GMT > >In fact, a virtual base class relates to a base class the same way, > >as a virtual member function relates to a non-virtual member function. > >You can override implementation of a virtual base class in the > >derived class.
> >> Nonsense - there's no such thing as overriding a virutal base class. > [quoted text clipped - 6 lines] > functions, there's no practical difference. It's when your virtual base > contains data members that the distinction is important. This way one can argue that virtual member functions are not overriden indeed, but only some values in virtual tables are substituted, and old implementations are in their places.
If the struct A contains a state and this state is changed in a constructor of the struct B, or extended in a declaration of the struct B, than other subobjects see subobject A after its initialization with the struct B. In this sence B overrides A's state.
 Signature Vladimir Nesterovsky e-mail: vladimir@nesterovsky-bros.com home: www.nesterovsky-bros.com
Gerhard Menzl - 17 Mar 2005 15:20 GMT > This way one can argue that virtual member functions are not overriden > indeed, but only some values in virtual tables are substituted, and [quoted text clipped - 4 lines] > struct B, than other subobjects see subobject A after its > initialization with the struct B. In this sence B overrides A's state. In C++, the term "overriding" has a well-defined technical meaning. It applies exclusively to member functions. There is no such thing as overriding of a class.
 Signature Gerhard Menzl
#dogma int main ()
Humans may reply by replacing the thermal post part of my e-mail address with "kapsch" and the top level domain part with "net".
Arnaud Debaene - 16 Mar 2005 18:57 GMT >> Nonetheless, I find it was a mistake to reuse the same keyword for >> something completely different, even if the inner implementation guts [quoted text clipped - 10 lines] > These member functions are overriden in descendants. > This way you are achieving a construction called interface. On the contrary, virtual inheritance make sense only for base classes that are not pure interfaces : the whole point of VI is to avoid duplication of data members : on a pure interface, you've got no data members, so no duplicates problems. The other effects you may see on function is side-effect of the "overiding through dominance" rule, but this not the purpose of VI.
Note that things can become a bit messy when you add delegates/events to the big picture. For example, I often declare C++ "interfaces" (no implementation and no "logical" data member) that contain one or more boost::signal (or LibSigC++ equivalent), because I do consider that the events that can be raisen are part of an interface. However, this make my "logical" interfaces physical "classes" (with data members). In such a case, VI has a meaning even for interfaces, but this is more a deficiency of the C++ model (lack of events/delegates/closures) than anything else.
Arnaud MVP - VC
Vladimir Nesterovsky - 17 Mar 2005 10:07 GMT > On the contrary, virtual inheritance make sense only for base classes that > are not pure interfaces I do not agree with such a categorical assertion. The whole idea of interfaces in com, java, .net is close to a virtual inheritance of a pure classes.
 Signature Vladimir Nesterovsky e-mail: vladimir@nesterovsky-bros.com home: www.nesterovsky-bros.com
Tom Widmer - 15 Mar 2005 15:41 GMT >>(e.g. the classic diamond virtual inheritance example). So your C class >>constructor needs to initialize the A base object as well as the B one - [quoted text clipped - 30 lines] > > in this case i end up with C and B using the same instance of A. ... when they are subobjects of a D. That's the classic diamond inheritance example I mentioned. When you create a D object, only D's initialization of A is used.
> multiple inheritance is the only scenario in which i can see a use for > virtual inheritance. > > looking at it like this, it seems that the only use of the 'virtual' keyword > in inheritance context is to say "whoever inherits from me has to initialize > my base class too" For single inheritance, yes - virtual inheritance is really for cases where multiple inheritance is, or may be in the future, employed. The standard library uses it for the ios base class of istream and ostream, to ensure that iostream only has one ios subobject (basic_ prefixes elided for clarity).
> this meaning seems unrelated to the meaning of virtual in the context of > member functions. is that correct? Yes.
Tom
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|