假设我们有一个基类A,很不幸的,A的析构函数是一个non-virtual。同时我们有一个派生类B,它派生自A。
我们定义了一个A类型指针,它指向的实际对象是B:

A * ptr = new B;

然后在程序的某处,我们不再需要B了,我们将指针ptr delete掉:

delete ptr;

注意new永远要和delete成队出现,除非你使用智能指针。这时由于A的析构函数是non-virtual,一个悲剧诞生:

C++中明确指出,当派生类对象经由一个基类指针被删除,而该基类带着一个non-virtual析构函数,其结果未定义--实际执行时通常发生的是对象的派生部分没有被销毁。也就是B对象部分发生内存泄漏。

问题的解决办法就是为多态基类A声明一个虚析构函数。简单吧,另一个更加通用的准则是:如果一个类拥有至少一个虚函数,那么这个类也应该要有一个虚析构函数,因为类中拥有虚函数已经表明该类将作为基类来使用,期待子类实现自己的虚函数,此时基类应该为析构函数作virtual声明。

反过来的另一条准则是,如果一个类不想作为基类,那么不要为其声明任何成员函数做virtual声明。为啥?virtual有代价啊。为了支持多态机制,编译器为类对象安插一个虚表指针,同时类也多了一张虚函数表。如果我们的类本来只有一个int类型的数据成员,在32bit机器上,sizeof(类)为4,而加了vptr后,sizeof(类)为8,类对象的大小整整翻了100%!

当然,就算我们的编程遵循了上面的准则,有时候还有有些许错误。切勿不要以没有任何虚函数的类作为基类。有时候由于我们的粗心大意或者在毫不知情的情况下我们可能会干这种事情。例如,我们想实现一个自己的容器MyList,并想借助STL的list来实现:

class MyList :public list
{//...
};

那么内存泄漏的问题又来了,STL中的list并不打算作为一个基类来使用,因此它的析构函数也不是一个virtual。类似的还有string、stl的vector、set、unordered_map等等。

好在,C++11 提供了final关键字,对于不想被继承的类,我们在其定义时加上final关键字:

class Super final
{//......
};

这样试图继承super时编译器将会报错。

转载于:https://www.cnblogs.com/QG-whz/p/5126078.html

多态基类与虚析构函数相关推荐

  1. 条款七 为多态基类声明virtual析构函数

    1.如果基类中的成员函数是virtual类型的,其继承类中相应的函数也是virtual类型,并且基类对象的引用指向继承类对象时, 基类就可以调用继承类函数,否则调用的是基类函数 class base ...

  2. C++学习笔记-----存在多态调用时,为基类定义虚析构函数

    在C++的继承体系中,构造函数和析构函数的执行顺序是完全相反的. 对于构造函数:从继承体系的最顶层的基类开始,一步步往下构建.即构造顺序是  基类--->>派生类. 对于析构函数:从继承体 ...

  3. 读书笔记_Effective_C++_条款七:为多态基类声明virtual析构函数

    严格来说,多态分为编译时多态和运行时多态,编译时多态是函数的重载,而运行时多态则是迟绑定技术,即根据基类指针或引用的实际指向来决定采取何种行动,一般来说,多态特指运行时多态.下面我们来举有关C++多态 ...

  4. Effective C++条款7:为多态基类声明virtual析构函数

    要点: 带多态性质的基类或者class中有virtual函数,就应该将析构函数声明为virtual,例如 class TimeKeeper { public:TimeKeeper();~TimeKee ...

  5. effective C++读书笔记--【条款07:为多态基类声明virtual析构函数】

    问题 base class的指针p,指向一个derived class,如果: base class带着一个non-virtual析构函数: derived class对象经由这个base class ...

  6. 转载:(C++)浅谈多态基类析构函数声明为虚函数

    原博文:https://www.cnblogs.com/AndyJee/p/4575810.html 主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C ...

  7. (C++)浅谈多态基类析构函数声明为虚函数

    主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...

  8. 基类、派生类、虚基类、虚函数、虚析构、纯虚函数、抽象类

    基类:被其它类通过继承方式作为父类继承的类称为基类:描述派生类的统一种类的方式. 派生类:通过继承其他类(并可能含有自定义成员)实现的子类:为提高代码的重用性及与同样继承于同一个父类的其它类形成统一种 ...

  9. 【虚基类、虚函数及应用】

    虚基类 1.虚基类存在的意义 当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类 ...

最新文章

  1. etcd 笔记(02)— etcd 安装(apt 或 yum 安装 、二进制包安装、Docker 安装 etcd、etcd 前端工具etcdkeeper)
  2. 【卷积神经网络结构专题】经典网络结构之VGG(附代码实现)
  3. metaweblog php,[PHP]利用MetaWeblog API实现XMLRPC功能
  4. php病毒图片后缀名,脚本图片类后门病毒的完美使用方法
  5. Chrome、Edge 合力围剿,Safari 夹缝求生?
  6. java文件读写的基本类_java常用工具类(三)—— 文件读取的操作类
  7. 如果你想精通一个行业,那必须进入这个行业
  8. Linux多进程编程(2)
  9. 【集群仿真】基于matlab匈牙利算法无人机队形重构集群仿真【含Matlab源码 1498期】
  10. 样条曲线、样条函数、python绘画样条曲线
  11. 真格量化学习处理——几个功能小函数
  12. 红米ac2100路由器刷入openwrt教程
  13. 深度残差网络+自适应参数化ReLU激活函数:调参记录2
  14. 【入门】QQ聊天机器人--HelloWorld篇
  15. server2003安装python3.4.4
  16. 网站地图制作百度地图google地图制作方法
  17. 疏忽了给该内页做外链
  18. 【理解数据结构】队列的实现(C语言)
  19. 奇虎360 -- 2013年校园招聘技术类笔试题
  20. imvu为什么显示无法连接服务器,IMVU服务器错误怎么办 服务器无法连接解决办法...

热门文章

  1. asm 32 /64
  2. 交叉编译arm-none-linux-gnueabi-gcc: No such file or directory
  3. 运行 composer update,提示 Allowed memory size of bytes exhausted
  4. 2017.7.6 linux 搭建ssh服务器 scp
  5. docker 感性介绍
  6. iOS内存管理编程指南
  7. 孙庆新:做产品,感觉从何而来
  8. 一个超酷的横向多列响应式布局效果
  9. windowservice创建及部署
  10. SET QUOTED_IDENTIFIER ON