This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Non-default ctors, virtual base classes, & multiple inheritance all at once!


    I'm having some trouble getting non-default constructors called for
virtual baseclasses in certain instances.. I've attached some code that
demonstrates this problem. In some cases, I can pass a parameter up the
tree to the virtual base class, in others, the default ctor is always
called even though my code clearly specifies the ctor taking a parm. Is
this a compiler bug or a language design issue?

    thanx & later,

        Ben Scherrey
//
//	vinherit.cpp - Tests resolution of virtual inheritance.
//

#include <iostream>
#include <string>

class A
{
public:
	A( void ) : v(0) { cout << "A ctor @ " << this << ", v = " << v << endl; }
	A( int a ) : v(a) { cout << "A int ctor @ " << this << ", v = " << v << endl; }
	A( const A& a ) : v(a.v) { cout << "A copy ctor @ " << this << " from " << &a << ", v = " << v << endl; }
	virtual ~A( void ) { cout << "A dtor @ " << this << ", v = " << v << endl; }

	virtual void f1( void ) { cout << "A::f1 v = " << v << endl; }
	virtual void f2( void ) = 0;
	int v;
};

class B : public A
{
public:
	B( void ) : A() { cout << "B ctor @ " << this << endl; }
	B( int i ) : A( i ) { cout << "B int ctor @ " << this << endl; }
	B( const B& a ) : A(a) { cout << "B copy ctor @ " << this << " from " << &a << endl; }
	virtual ~B( void ) { cout << "B dtor @ " << this << endl; }	
	virtual void f2( void ) { cout << "B::f2" << endl; }
};

class C : public virtual A
{
public:
	C( void ) : A() { cout << "C ctor @ " << this << endl; }
	C( int i ) : A(i) { cout << "C int ctor @ " << this << endl; }
	C( const C& a ) : A(a) { cout << "C copy ctor @ " << this << " from " << &a << endl; }
	virtual ~C( void ) { cout << "C dtor @ " << this << endl; }
	virtual void f2( void ) { cout << "C::f2" << endl; }
};

template < typename X >
class HoldX : public virtual X
{
public:
	template < typename T >
	HoldX( T t ) : X( t ) { cout << "T HoldX ctor @ " << this << endl; }
	HoldX( void ) : X() { cout << "HoldX ctor @ " << this << endl; }
	HoldX( const HoldX& a ) : X(a) { cout << "HoldX copy ctor @ " << this << " from " << &a << endl; }
	virtual ~HoldX( void ) { cout << "HoldX dtor @ " << this << endl; }
	virtual void f2( void ) { cout << "HoldX::f2" << endl; }	
};

template < typename Y, typename X >
class HoldY : public Y, public HoldX< X >
{
public:
	template < typename T >
	HoldY( T t ) : Y( t ), HoldX< X >( t ) { cout << "T HoldY ctor @ " << this << endl; }
	HoldY( void ) : Y(), HoldX< X >() { cout << "HoldY ctor @ " << this << endl; }
	HoldY( const HoldY& a ) : Y(a), HoldX< X >(a) { cout << "HoldY copy ctor @ " << this << " from " << &a << endl; }
	virtual ~HoldY( void ) { cout << "HoldY dtor @ " << this << endl; }
	virtual void f2( void ) { cout << "HoldY::f2" << endl; }
};

template < typename Y, typename X >
class HoldZ : public Y, virtual public HoldX< X >
{
public:
	template < typename T >
	HoldZ( T t ) : Y(t), HoldX< X >(t) { cout << "\nT HoldZ ctor @ " << this << endl; }
	HoldZ( void ) : Y(), HoldX< X >() { cout << "\nHoldZ ctor @ " << this << endl; }
	HoldZ( const HoldZ& a ) : Y(a), HoldX< X >(a) { cout << "\nHoldZ copy ctor @ " << this << " from " << &a << endl; }
	virtual ~HoldZ( void ) { cout << "HoldZ dtor @ " << this << endl; }
	virtual void f2( void ) { cout << "HoldZ::f2" << endl; }
};

int main( void )
{
	cout << "Test case for virtual inheritance." << endl;

	cout << "\nConstructing HoldX< A > X1;" << endl;
	HoldX< A > X1;		// OK

	cout << "\nConstructing HoldX< A > X2(2);" << endl;
	HoldX< A > X2(2);	// OK

	cout << "\nConstructing HoldX< B > X3;" << endl;
	HoldX< B > X3;		// OK

	cout << "\nConstructing HoldX< B > X4(4);" << endl;
	HoldX< B > X4(4);	// OK

	cout << "\nConstructing HoldX< C > X5;" << endl;
	HoldX< C > X5;		// OK

	cout << "\nConstructing HoldX< C > X6(6);" << endl;
	HoldX< C > X6(6);	// Huh? Why no A(int) call?

	cout << "\nConstructing HoldY< B, A > Y1;" << endl;
	HoldY< B, A > Y1;	// OK

	cout << "\nConstructing HoldY< C, A > Y2;" << endl;
	HoldY< C, A > Y2;	// OK

	cout << "\nConstructing HoldY< C, A > Y3(3);" << endl;
	HoldY< C, A > Y3(3);// Huh? No A(int) again!

	cout << "\nConstructing HoldZ< B, A > Z1;" << endl;
	HoldZ< B, A > Z1;	// OK

	cout << "\nConstructing HoldZ< C, A > Z2;" << endl;
	HoldZ< C, A > Z2;	// OK

	cout << "\nConstructing HoldZ< C, A > Z3(3);" << endl;
	HoldZ< C, A > Z3(3);// Again no A(int)!
	Z3.f1();
	Z3.f2();

	cout << "\nConstructing C C1(1);" << endl;
	C C1(1);			// OK

	cout << "\nTest complete." << endl;
	return 0;
}

//
// eof( vinherit.cpp )
//

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]