虚析构函数

来源:互联网 发布:微信客户端 mac 编辑:程序博客网 时间:2024/05/26 15:58

如果你打算让你的类支持继承,那么即使你的类不用其它虚函数,也最好还是要一个虚析构函数。

class Base {

public :

          void fun ();

};

 

class Derived: public Base {

public:

         void test ();

};

Base *bp;

bp =  new Derived;

delete bp;

这里一个基类指针bp,来删除派生类对象。因为基类没有虚析构函数,所以delete的时候只会调用基类的析构函数,而派生类的析构函数不会被调用到。这样就有可能造成派生类的资源没有被释放掉,引起内存泄漏。

为了解决这个问题,我们就需要虚析构函数出马了。

改写基类如下:

class Base {

public :

          void fun ();

          vritual ~Base();

};

派生类不用做任何改变,delete bp;这条语句执行时就能够正常调用派生类和基类的析构函数来销毁对象了。

 

首先,虚函数在继承层次结构中总是会自动地从基类传播下去的。因此,派生类中的同名成员函数都变成了虚函数,派生类中的同名成员函数的virtual说明可以省略。

而虚析构函数相对于普通的虚函数又特别一点,虽然基类和派生类构造函数名字不一样,但是如果基类的析构函数是虚的,那么派生类的析构函数也自然是虚的 ---也不需要显示地指定virtual说明。

编译器会把Derived的析构函数放在dp的虚函数表中-----覆盖掉虚函数表中原先放的Base的析构函数。所以delete dp;的时候编译器从虚函数表中拿到的析构函数就是Derived的析构函数。

只要派生类的析构函数有机会执行,那么其基类的析构函数就会在派生类析构函数中被调用。(实际上,编译器将派生类的析构函数进行了扩展,无论虚与非虚)。参考《Inside The C++ Object Model》

这样,delete dp;的时候,编译器就会先调用派生类的析构函数,然后再调用基类的析构函数了。这个顺序刚好与构造函数的顺序相反。

 

原创粉丝点击