This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Non-default ctors, virtual base classes, & multiple inheritance all at once!
- To: gcc at gcc dot gnu dot org
- Subject: Non-default ctors, virtual base classes, & multiple inheritance all at once!
- From: Benjamin Scherrey <scherrey at switchco dot com>
- Date: Tue, 05 Sep 2000 13:58:20 -0400
- Organization: Proteus Technologies, Inc.
- Reply-To: scherrey at switchco dot com
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 )
//