[comp.lang.c++] virtual base classes

lpringle@bbn.com (Lewis G. Pringle) (07/25/89)

I am a bit confused about calling constructors of virtual base
classes.  According to page 363(bottom) of Lippman, "A base class
specified as virtual must, if it defines any constructors define a
constructor that does not require an argument list..."

I have seen this contradicted elsewhere, but also seen it claimed elsewhere.

Later (page 365) Lippman says "A virtual base class is initialized by its
most derived class."  Now this makes loads of sense, but also seems to make
unnessary the above constraint.

Can anyone clarify if it is really necessary to provide a constructor with no
args (if any) for a virtual base class.  If it is necessary, then why??

					Appropriate Remarks,
							Lewis.
"OS/2: half an operating system for half a computer."

In Real Life:		Lewis Gordon Pringle Jr.
Electronic Mail:	lpringle@labs-n.bbn.com
Phone:			(617) 873-4433

stanl@cbnewsm.ATT.COM (stanley.b.lippman) (12/28/89)

*** Shankar Unni writes:

Consider the following situation:

    class A {public: int a_mem;};
    
    class B : virtual public A {};
    
    class C : public A {};
    
    class D : public B, virtual public C {};
    


                A   A       <<< ********** revised drawing
	       /    | 
     virtual  /     | 
	     /      | 
	    B       C
	     \     /
	      \   /  virtual
	       \ /
	        D


Questions:

   (a) How many "A"'s are there in "D"?

*****> two

   (b) If there is more than one, is the following access unambiguous, and
       if so, which "A" does it refer to:  "D::a_mem"

*****> no, it is ambiguous

My copy of cfront (2.0) seems to think that:

   (a) there is only *one* A in D.

*****> no, look again -- there are two, one within the C sub-object
       of D and the virtual OA instance:

struct A {	/* sizeof A == 4 */
int a_mem__1A ;
};

struct B {	/* sizeof B == 8 */
struct A *PA;
struct A OA;
};

struct C {	/* sizeof C == 4 */
int a_mem__1A ;  // members of A unrolled ...
};

struct D {	/* sizeof D == 16 */
struct A *PA;   // members of B unrolled ...
struct C *PC;
struct C OC;	// non-virtual instance of A within OC
struct A OA; 	// virtual instance of A from B
};

   (b) (this is therefore moot).

*****> cfront actually has a bug in that it is
       choosing the instance associated with the
       virtual object associated with B -- it should
       be ambiguous and will be fixed in 2.1

	d . PA-> a_mem__1A = 1 ;  // generated cfront


stan lippman
at&t bell laboratories
warren, new jersey

shankar@hpclisp.HP.COM (Shankar Unni) (01/03/90)

> 
>               A   A       <<< ********** revised drawing
> 	       /    | 
>    virtual  /     | 
> 	     /      | 
> 	    B       C
> 	     \     /
> 	      \   /  virtual
> 	       \ /
> 	        D
> 
> 
>    (a) there is only *one* A in D.
> 
> *****> no, look again -- there are two, one within the C sub-object
>        of D and the virtual OA instance:

Yeah, I looked at the generated code, but it seemed to me that one of the
subobjects was not being used. So I jumped to the conclusions that I
posted. Hmm, I suppose I should read the generated code a little more
carefully.

> *****> cfront actually has a bug in that it is
>        choosing the instance associated with the
>        virtual object associated with B -- it should
>        be ambiguous and will be fixed in 2.1
> 
> 	d . PA-> a_mem__1A = 1 ;  // generated cfront
> 

Right - that's what I saw, but I tried to diagnose the problem too soon and
jumped to the wrong conclusion.


Thanks for the clarification.
-------
Shankar Unni.
HP/California Language Lab.