编码实现C++类的时候,一般都会把析构函数定义为虚函数,不管这个类是基类还是继承类。
先代码实验
1.析构函数为非虚构
#include <iostream>
using namespace std;
class CBase
{
public:
CBase(){}
~CBase(){cout << "base destructor" << endl;}
};
class CDerived : public CBase
{
public:
CDerived(){}
~CDerived(){cout << "derived destructor" << endl;}
};
int main()
{
CDerived* cd = new CDerived();
delete cd;
cout << "-----------------" << endl;
CBase* cb = new CBase();
delete cb;
cout << "-----------------" << endl;
CBase* p = new CDerived();
delete p;<pre name="code" class="html"> return 0;
}
运行结果:
derived destructor
base destructor
-----------------
base destructor
-----------------
base destructor
可以发现,使用多态的时候,出问题了。
2.析构函数为虚函数
#include <iostream>
using namespace std;
class CBase
{
public:
CBase(){}
virtual ~CBase(){cout << "base destructor" << endl;}
};
class CDerived : public CBase
{
public:
CDerived(){}
~CDerived(){cout << "derived destructor" << endl;}
};
int main()
{
CDerived* cd = new CDerived();
delete cd;
cout << "-----------------" << endl;
CBase* cb = new CBase();
delete cb;
cout << "-----------------" << endl;
CBase* p = new CDerived();
delete p;<pre name="code" class="html"> return 0;
}
derived destructor
base destructor
-----------------
base destructor
-----------------
derived destructor
base destructor
这就正常了。
3.原因
对于
CDerived* cd = new CDerived();
delete cd;
指针cd指向CDerived对象,调用CDerived类的析构函数,因为析构了继承类,所以,之后会析构基类
对于
CBase* cb = new CBase();
delete cb;
指针cb指向CBase类的对象,调用CBase类的析构函数。
对于
CBase* p = new CDerived();
delete p;
基类使用虚析构函数时,动态联编,指针指向的是CDerived类的对象,调用CDerived类的析构函数,因为析构了继承类,所以,之后会析构基类
基类没使用虚析构函数时,静态联编,指针指向CBase类的对象,调用CBase类的析构函数。就不会调用继承类的析构函数了。