关于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."

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值