关于C++虚析构函数

在上一篇博文《关于C++对象的自杀 》末尾提到了基类的虚析构函数 ,于是再添一篇。

什么时候析构函数需要加个virtual 来修饰呢?

当要通过指向基类的指针删除子类对象时。

Why?

这是为了保证基类和子类的析构函数都得到调用。

个人理解 :因为基类类型的指针指向的是子类对象中的基类部分,如果析构函数不为虚函数,则无法调用到子类的析构函数。

如下代码:

#include <iostream> using namespace std; class ClsBase{ public: ClsBase(){ cout << "ClsBase constructor." << endl; } ~ClsBase(){ cout << "ClsBase destructor." << endl; } }; class ClsDerived : public ClsBase { public: ClsDerived(){ cout << "ClsDerived constructor." << endl; } ~ClsDerived(){ cout << "ClsDerived destructor." << endl; } }; int main(){ ClsBase *p = new ClsDerived(); delete p; return 0; }

输出为:

ClsBase constructor. ClsDerived constructor. ClsBase destructor.

说明 了基类析构函数不为虚函数时,delete指向基类的指针时无法调用到子类的析构函数。

将基类析构函数修改为虚函数,得到如下代码:

#include <iostream> using namespace std; class ClsBase{ public: ClsBase(){ cout << "ClsBase constructor." << endl; } virtual ~ClsBase(){ cout << "ClsBase destructor." << endl; } }; class ClsDerived : public ClsBase { public: ClsDerived(){ cout << "ClsDerived constructor." << endl; } ~ClsDerived(){ cout << "ClsDerived destructor." << endl; } }; int main(){ ClsBase *p = new ClsDerived(); delete p; return 0; }

输出为:

ClsBase constructor. ClsDerived constructor. ClsDerived destructor. ClsBase destructor.

此时,子类的析构函数得到调用。

个人理解

这是因为基类中将析构函数声明为虚函数,则析构函数(的索引/指针)会被放在虚表vtbl中。

在继承过程中,vtbl属于基类部分,即基类类型的指针p可以指到的范围。

并且,析构函数的虚函数性质会在继承过程中得到保持(虽然函数名不同),于是子类的析构函数也位于虚表中,确保delete p时可以调用到子类的析构函数。

于是,析构函数自底向上得到调用了。

最后引用C++ FAQ的一个段落:

BTW, if you're interested, here are the mechanical details of why you need a virtual destructor when someone says delete using a Base pointer that's pointing at a Derived object. When you say delete p , and the class of p has a virtual destructor, the destructor that gets invoked is the one associated with the type of the object *p , not necessarily the one associated with the type of the pointer. This is A Good Thing. In fact, violating that rule makes your program undefined. The technical term for that is, "Yuck."

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值