guest@masscomp.UUCP (Mr Guest) (07/05/89)
Consider the following template for a set of classes involving virtual base classes with constructors. class common { common () {} }; class virtual_1 : virtual public common { virtual_1 () : common () {} }; class virtual_2 : virtual public common { virtual_2 () : common () {} }; Each of the two classes derived from common has their own constructor which "call" the constructor for their base class. Now derive a class from both of these: class both : public virtual_1, public virtual_2 { both () : virtual_1 (), virtual_2 () {} }; It seems to me that the constructor for "common" will be called twice. What am I doing wrong? - Keith
jima@hplsla.HP.COM (Jim Adcock) (07/07/89)
//It seems to me that the constructor for "common" will be called twice. //What am I doing wrong? - Keith //Maybe nothing -- I made the following slight mods to your example and //under my compiler common() only gets called once. Is this what you //wanted? See Lippman pages 360-370. #include <stdio.h> class common { public: common () {printf("common ");} }; class virtual_1 : virtual public common { public: virtual_1 () : common () {printf("virtual_1 ");} }; class virtual_2 : virtual public common { public: virtual_2 () : common () {printf("virtual_2 ");} }; class both : public virtual_1, public virtual_2 { public: both () : virtual_1 (), virtual_2 () {printf("both ");} }; main() { common c; printf("\n"); virtual_1 v1; printf("\n"); virtual_2 v2; printf("\n"); both b; printf("\n"); } /************* gives this output ***************/ common common virtual_1 common virtual_2 common virtual_1 virtual_2 both
wmm@sdti.com (0006-William M. Miller(0000)) (07/07/89)
In article <1429@masscomp.UUCP> loepere@westford.ccur.com (Keith Loepere) writes: > >Consider the following template for a set of classes involving virtual >base classes with constructors. > >class common >{ > common () {} >}; > >class virtual_1 : virtual public common >{ > virtual_1 () : common () {} >}; > >class virtual_2 : virtual public common >{ > virtual_2 () : common () {} >}; > >class both : public virtual_1, public virtual_2 >{ > both () : virtual_1 (), virtual_2 () {} >}; > >It seems to me that the constructor for "common" will be called twice. >What am I doing wrong? - Keith Nothing. The invocations of the "common" constructor in the two intermediate classes are ignored when creating an object of class "both." When you make a "both" object, "common()" is invoked, then "virtual_1()," then "virtual_2()," then "both()." This has changed a bit in the most recent 2.0 language definition. It used to be the case that a virtual base class could not be explicitly initialized. Now the rules allow for that possibility. The new 2.0 definition uses the terminology "most derived class" to refer to, for example, your "both" class. The rules basically say that the most derived class is considered to be directly based on *every* virtual base class in the inheritance DAG and can therefore give arguments to their constructors. To jazz up your example a bit, class common { public: common(int); }; class virtual_1: virtual public common { public: virtual_1(): common(5) {} }; class virtual_2: virtual public common { public: virtual_2(): common(10) {} }; class both: virtual public virtual_1, virtual public virtual_2 { public: both(): common(15) {} }; virtual_1 v1; virtual_2 v2; both b; The "common" object in "v1" will be initialized with the value 5; in "v2," with the value 10; and in "b," with the value 15. -- Non-disclaimer: My boss and I always see eye-to-eye (every time I look in the mirror). ...!genrad!mrst!sdti!wmm