class A
{
public:
A(){cout<<"A constructor"<<endl;}
virtual ~A(){cout<<"A destructor"<<endl;}//输出改为virtual
};
class B
{
public:
B(){cout<<"B constructor"<<endl;}
virtual ~B(){cout<<"B destructor"<<endl;}
};
class C:public A,public B
{
public:
C(){cout<<"C constructor"<<endl;}
~C(){cout<<"C destructor"<<endl;}
};
class D:public B,public A
{
public:
D(){cout<<"D constructor"<<endl;}
~D(){cout<<"D destructor"<<endl;}
};
int main(int argc, char* argv[])
{
A* pa = new C;
delete pa;
cout << "===========" << endl;
B* pb = new D;
delete pb;
return 0;
}
/* 首先基类A,B均有虚析构函数,所以会沿着析构函数链进行析构,不会存在对象部分析构的情况。
另外,请注意多重继承中声明次序和构造/析构的次序
class C:public A,public B===>
A constructor 构造次序:先基类,后子类;基类的构造次序为先A,后B
B constructor
C constructor
C destructor 析构次序:先子类,后基类;基类的析构次序为先B,后A
B destructor
A destructor
===========
class D:public B,public A===>
B constructor 构造次序:先基类,后子类;基类的构造次序为先B,后A
A constructor
D constructor
D destructor 析构次序:先子类,后基类;基类的析构次序为先A,后B
A destructor
B destructor
*/
几种可能:
A,B类中均没有虚析构函数
class A
{
public:
A(){cout<<"A constructor"<<endl;}
virtual ~A(){cout<<"A destructor"<<endl;}//输出改为virtual
};
class B
{
public:
B(){cout<<"B constructor"<<endl;}
virtual ~B(){cout<<"B destructor"<<endl;}
};
A* pt = new C;
delete pt;
输出结果:
A constructor
B constructor
C constructor
C destructor
B destructor
A destructor
只在其中一个类中存在虚析构函数
class A
{
public:
A(){cout<<"A constructor"<<endl;}
~A(){cout<<"A destructor"<<endl;}
};
class B
{
public:
B(){cout<<"B constructor"<<endl;}
virtual ~B(){cout<<"B destructor"<<endl;}
};
class C:public A,public B
{
public:
C(){cout<<"C constructor"<<endl;}
~C(){cout<<"C destructor"<<endl;}
};
B* pa = new C;
delete pa;
输出结果:
A constructor
B constructor
C constructor
C destructor
B destructor
A destructor
============================
class A
{
public:
A(){cout<<"A constructor"<<endl;}
~A(){cout<<"A destructor"<<endl;}//输出改为virtual
};
class B
{
public:
B(){cout<<"B constructor"<<endl;}
virtual ~B(){cout<<"B destructor"<<endl;}
};
class C:public A,public B
{
public:
C(){cout<<"C constructor"<<endl;}
~C(){cout<<"C destructor"<<endl;}
};
int main(int argc, char* argv[])
{
A* pa = new C;
delete pa;
return 0;
}
输出结果:
A constructor
B constructor
C constructor
A destructor
观察输出,我们可以得到如下结论:
无论多重继承中的基类任然需要遵循Effective C++中基类的设计原则---如果一个类被作为基类使用,需要提供虚析构函数。
对于多重继承中没有虚析构的基类,如果用基类指针操作子类对象那么会出现资源泄露。