继承和多态---虚析构函数(二)

当派生类的对象从内存中撤销时一般先调用派生类的析构函数,然后在调用基类的析构函数,但是如果用new运算符建立了一个临时对象,若基类中有析构函数,并且定义了一个指向该基类的指针变量,在程序中用带指针的delete运算符撤销时系统只会执行基类的析构函数,而不执行派生类的析构函数。

如下所示:

当然,这只是一个示意的程序,p是指向基类的指针变量,指向new动态开辟的存储空间,然后希望在程序结束时用delete释放p所指向的空间,但是运行结果确实是:

spacer.gif 

只是执行了基类的析构函数而并没有执行派生类的析构函数,

因为:如果析构函数不被声明为虚析构函数,则编译器实行静态绑定,删除基类指针时,只会调用基类的析构函数,而不调用派生类的析构函数,这样就会造成派生类的对象析构不完整。

   如果希望能够执行派生类的析构函数。则将基类 的析构函数声明为虚函数,则运行结果会变为:

spacer.gif 

 

(1)当基类的析构函数声明为虚函数时,由该基类所派生的所有派生类的析构函数也都自动成为虚函数,即使派生类的虚函数与基类的虚函数名字不相同。

(2)最好把基类的析构函数声明为虚函数,这将使所有派生类的析构函数成为虚函数,这样如果程序显示的调用delete运算符准备删除一个对象时,而delete运算符的的操作对象用了指向派生类的基类指针,系统会自动调用相应类的析构函数。

(3)构造函数不能声明为虚函数,因为在执行构造函数时对象还没建立,还谈不上把函数与类对象的绑定。

#include<iostream>

using namespace std;

//定义基类point对象

class Point

{

public:

//定义point构造函数

Point()

{}

virtual ~Point()

{

cout<<"~Point"<<endl;

}

};

 

class Circle:public Point

{

public:

Circle()

{}

~Circle()

{

cout<<"~Circle"<<endl;

}

private:

int radus;

};

int main()

{

Point *p=new Circle;

delete p;

system("pause");

return 0;

}