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

C++之一些事一些情--虚析构函数

2013-12-16 22:34 155 查看
《Effective C++》条款14:确定基类有虚析构函数。为什么要这样做呢?引用百度百科对虚析构函数的解释:

虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象”。

以下是两个类的声明,其中Base类为基类,而Derived类继承自Base类:

class Base
{
public:
Base(){ cout<<"Base Constructor"<<endl; }
~Base(){ cout<<"Base Deconstructor"<<endl; }

};

class Derived : public Base
{
public:
Derived(){ cout<<"Derived Constructor"<<endl; }
~Derived(){ cout<<"Derived Deconstrutor"<<endl; }
};

下面为相应的测试代码:

Base *ptr = new Derived;
delete ptr;

上面测试代码的输出结果如下:

Base Constructor
Derived Constructor
Base Deconstructor

从上面的输出结果可以看到,子类Derived的析构函数并没有被调用。若子类Derived的析构函数里面会做一些释放资源操作的话,那么析构函数里面的代码将会徒劳无功了,举个例子,对于STL里面的智能指针auto_ptr,所谓智能就是因为auto_ptr对象在结束生存期时,会在析构函数里面自动调用delete操作以释放所指向的内存空间,若auto_ptr因为某些公有的操作继承自一个没有声明虚析构函数的父类,那么智能指针将不再智能了,随之而来就是内存泄露问题了。

当然,并不是要把所有类的析构函数都声明为虚函数。因为当编译器发现类中有虚函数的时候,就会给类创建一个虚表,用来存放每个虚函数的地址;同时编译器会另外为每个类对象添加一个虚指针,用于指向对象所属类的虚表,这样就会使得类对象占用了更多的内存空间。因此,当一个类被用来作为基类的时候,才把析构函数声明为虚函数。但众所周知,现在普通PC机可用的内存空间越来越大了,也没有人确定一个类以后不会被继承,为了安全起见,个人还是建议把类的析构函数都声明为虚函数。

若将基类Base的析构函数声明为virtual,则上面的测试代码将会得到以下正确的输出结果:

Base Constructor
Derived Constructor
Derived Deconstrutor
Base Deconstructor
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: