您的位置:首页 > 编程语言 > C语言/C++

《Effective C++》条款07:为多态基类声明virtual析构函数

2018-03-26 11:41 387 查看
   
class Base_A
{
public:
Base_A():element(0) {}
~Base_A() { cout << "调用A的析构函数" << endl; }
void print(int a) { cout << a << endl; }
void print(float a) { cout << a << endl; }
private:
int element;

};

class Derived_B :public Base_A
{
public:
Derived_B():elem_B(1) {}
~Derived_B() { cout << "调用B的析构函数!"<<endl; }
using Base_A::print;

void print(const string& str) { cout << str << endl; }
void print() { Base_A::print(elem_B); }
private:
int elem_B;
};
int main()
{
int i = 0;
while(i <=0)
{
Base_A *b=new Derived_B;
delete b;
i++;
}
}
结果如下图:



先看上面这个例子,Derived_B是Base_A的派生类,但是在基类中Base_A的析构函数不是虚析构函数。并且需要注意的是主函数中new  Derived_B产生的对象的指针指向的Base_A的。这个指针的生命周期是while循环中,一旦跳出while循环之后,编译器就会调用析构函数,析构掉b指针。但是实际上产生的是一个Derived_B对象,这个对象的内存空间里既包含自身的资源,同时也包含基类的资源。那么当指针b的生命周期结束之后,调用Base_A的析构函数只能释放掉Base_A的资源,那么还有Derived_B的资源未被释放,造成了“局部析构”对象,可能会导致资源泄露。
    其实解决的办法也很简单,就是为你想要实现多态的基类声明一个virtual析构函数。所以把上面Base_A 中的析构函数改成virtual析构函数,就可以解决该问题了。一旦指针b的生命周期结束后调用会调用Derived_B的析构函数和Base_A的析构函数,释放掉资源,从避免了“局部析构的问题”。修改之后运行的结果如下:



带有多态性质的基类应该声明一个virtual析构函数。或者说如果这个类中具有一个或一个以上的virtual函数,那么你就应该给这个类声明一个虚析构函数。但是如果的设计一个类的目的不是想要作为基类来使用的,那么你就没有必要为这个类声明一个virtual的析构函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: