C++虚析构函数解析
当派生类对象从内存中撤销时一般先运行派生类的析构函数,然后再调用基类的析构函数。
如果用new运算符建立的派生类的临时对象,对指向基类的指针指向这个临时对象当用delete运算符撤销对象时,系统执行的是基类的析构函数,而不是派生类的析构函数,不能彻底的“清理现场”。解决的方法是将基类及派生类的析构函数设为虚函数,这时无论基类指针指向哪个派生类对象,系统会采用动态关联,调用相应的析构函数对对象进行清理。
class Point
{
public :
Point(){};
~Point(){ std::cout << "Point destructor" << std::endl; }
private :
};
class Circle: public Point
{
public :
Circle(){};
~Circle(){ std::cout << "Circle destructor" << std::endl; };
private :
};
int _tmain( int argc , _TCHAR* argv[])
{
Point *p = new Circle;
delete p;
getchar();
return 0;
}
程序运行结果如下:
下面将基类的析构函数改成虚析构函数
virtual ~Point(){ std::cout << "Point destructor" << std::endl; }
其它的不变,再运行:
这样就达到我们的目的了,基类,派生类都调用了析构函数,另外需要注意的是
在基类的析构函数声明为虚函数时,由该基类派生的析构函数也自动成为虚函数,即使派生类的析构函数与基类的析构函数名字不相同。
程序中显示的用delete运算符删除一个对象,而这个对象是指向派生类对象的基类指针,系统调用相应派生类的析构函数。
如果程序中的局部对象离开其作用域,系统会隐式地调用其析构函数
咱们增加一个函数并从写main函数:
Point *fc()
{
Circle cl;
Point *p = new Circle;
return p;
}
int _tmain( int argc , _TCHAR* argv[])
{
Point *q = fc();
delete q;
getchar();
return 0;
}
运行结果如下:
在上例中,函数非常fc的内部定义了两个对象:c1和p所指向的Circle类对象。对象cl在函数fc结束时执行Circle的析构函数,撤销局部变量c1.p所指向的对象的地址通过函数返回值赋予q,q所指向的对象在执行delete时执行析构函数。