首先看一段示例代码:

class 

上面代码中 class AX 的析构函数不会被调用,如果在 AX 析构函数中需要进行一些资源释放工作(一般都是如此)则这些工作不会被执行。解决的方法就是将基类析构函数声明为虚函数,如下:

class 

看起来很完美对不对。然而本文的目的并不是介绍如何使用虚析构函数,恰恰相反,本文想表达的观点是:当需要用虚析构解决问题时,通常意味着代码设计出问题了

上面一段代码是所谓的“示例代码”,很少有示例代码的代码逻辑能直接在工程中使用,因为它们通常都太简单了,而实际工程通常都是复杂的,甚至有一些完全无法在工程中使用。这也是为什么很多知识学起来似乎很简单用起来却很难的原因。

接下来我们按照尽量贴近实际工程的方式修改上述代码:

// A.h

代码被分开到了三个文件中,Method() 中的代码实际使用的是 class A,并不需要了解 class AX 的定义,所以我们引入工厂模式来消除 method() 函数对 class AX 的依赖:

// A.h

终于有点工业强度代码的样子了。看起来似乎没什么问题,对吗?那接着来。

有了工厂模式,可以玩很多花活儿了,比如如果 class AX 的对象会被频繁创建和销毁影响性能,所以我们引入内存池分配内存,或者建个对象池对使用完毕的对象销毁再利用等等。AFactory::CreateAX 可能被改成下面的样子:

A

发现什么了吗?函数 Method() 中原本正确的代码现在变成错误代码了。我们常常强调代码的健壮性,什么叫健壮的代码不太好描述,什么叫脆弱的代码看这里就知道了:我们修改了某个位置的代码,然后在千里之外的其他地方引发了BUG。

更严重的是,不仅仅是修改内存分配方式这种明显的行为,其他诸如升级编译器版本甚至修改编译参数都可能产生同样的效果。在大规模的项目中,class A 和 Method() 的代码分属不同的开发人员、甚至不同团队、不同公司是很平常的事情,这种情况下如此脆弱的代码非常难以维护。

本质上是因为虚析构函数假定派生类对象必须使用 new 创建,使得调用代码和实现代码多出了一条隐藏的强耦合关系。更好的处理方式是如果一个类需要被继承,那么直接把其析构函数声明为 protected,禁止调用代码使用 delete 释放基类指针。可以在创建对象时使用智能指针,这样调用代码就不必关心对象如何创建和如何释放的问题。

虚析构的另一个问题是会改变虚函数表的结构,导致跨语言使用虚函数表时出现兼容性问题,情况比较少见,这里不再展开细说。

只有在设计上需要在基类中处理派生类释放时才必须使用虚析构(比如以继承实现的方式实现侵入式引用计数),其他情况都可以绕开并且比使用虚析构带来更好的代码健壮性。

所以,如果发现需要使用虚析构解决问题,意味着代码该重构了。

c++ map 析构函数_说说C++的虚析构函数相关推荐

  1. vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数...

    今天主要讲的是虚函数的override与overload的区别.首先我们来看一段代码: 示例代码 #include <stdio.h> #include <string> #i ...

  2. C++中基类的析构函数为什么要用virtual虚析构函数

    知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...

  3. C++编程进阶2(编译器在类内默认生成的函数讨论以及纯虚析构函数)

    三.编译器默认提供的类内函数讨论 1.当写下一个空类时,编译器会在必要的时候默认提供四个函数:构造.拷贝构造.operator=和析构函数,而且都是public的 class Empty{ }; 上述 ...

  4. c++远征之继承篇——隐藏,isa,虚析构函数

    一.隐藏 父子关系. 成员(数据成员或者成员函数)同名: 此时子类中会隐藏父类中的同名成员. 无法函数重载,只会隐藏! 如果想访问父类中的同名成员,需要 :: 操作. 访问父类同名函数的方法 二.is ...

  5. C++——虚函数、虚析构函数、纯虚函数、抽象类

    目录 一.虚函数 1.什么是虚函数? 2.虚函数的作用 3.虚函数的参数 4.虚函数代码示例 二.虚析构函数 1.什么是虚析构函数? 2.虚析构函数的作用 3. 构造函数 4.为什么构造函数不能是虚函 ...

  6. 6.4虚析构函数和纯虚析构函数

    虚析构函数和纯虚析构函数 如果有一定基础的伙伴来看这篇文章之前应该都知道虚析构函数的用途,虚析构函数就是防止有有没有释放干净的内存,防止内存泄漏. 没学过也没有关系我们通过了解原理的过程来学习这个虚析 ...

  7. c++ map 析构函数_C++|类继承关系中的虚函数、虚析构函数、虚基类

    在继承关系中,虚函数.虚析构函数.虚基类中使用的关键字virtual都是在告诉编译器,此处要进行特殊处理: 虚函数:函数重写时的要求编译器动态绑定来实现多多态 : 虚析构函数:当基类指针指向在堆内实现 ...

  8. C++_类和对象_C++多态_虚析构和纯虚析构函数---C++语言工作笔记074

    然后我们再来看,虚析构和纯虚析构函数的用法,上面有大体的介绍了. 但是我们还是用一个例子来说明一下更好. 首先,我们去创建一个Animal类,类中我们去写上一个spreak这个,纯虚函数,然后,让我们 ...

  9. C++中的虚析构函数

    Cpp中的虚析构函数 1.虚析构函数的作用:为了避免内存泄漏,而且是当子类中会有指针成员变量时才会使用到.即虚析构函数使得在删除指向子类对象的基类指针时,可以调用子类的析构函数来实现释放子类中堆内存的 ...

最新文章

  1. malloc(0)-malloc 0 字节
  2. 设计模式之C#实现--FactoryMethod
  3. Linux 工具进阶
  4. IO模式——同步(堵塞、非堵塞)、异步
  5. Mac版 Android Studio Android Sdk 更新方式
  6. nodejs 当前文件路径_NodeJs的几种文件路径
  7. 通信原理2习题课汇总(随机信号、信道、最佳接收)
  8. [译]如何在visual studio中调试Javascript
  9. 石化总部java面试题_中国石化面试经验
  10. 紫米创始人张峰兼任小米笔记本总经理
  11. 微软小冰学会画画了,堪称复活近代画家,还能命题作画
  12. 如何成为优秀的技术人员
  13. android ble 写失败,Android低功耗蓝牙BLE写入数据很大几率会失败 求解
  14. 服务器ie浏览器总是未响应怎么办,电脑ie浏览器老是无响应怎么办
  15. 华为机试HJ70:矩阵乘法计算量估算
  16. 研究生实证论文数据经验分享
  17. Halcon:多张图片合并成一张图片
  18. WordPress文章发布失败或更新失败解决方法
  19. 职高 计算机应用与基础测试卷,职高二计算机应用基础期末测试.doc
  20. python语音合成并播放_语音合成篇

热门文章

  1. JDK 监控和故障处理工具总结
  2. linux fedora35让GRUB 2记住上一次启动的操作系统
  3. K8S创建role命令示例
  4. hbase hbck命令示例
  5. 【收藏】在QGIS中导入GOOGLE、BING等地图和卫星影像(插件方式和XYZ方式)
  6. docker容器内部使用vim
  7. char型变量中能不能存储一个中文汉字?为什么?
  8. elasticsearch集群配置文件详述
  9. Spring注解开发-Bean注册
  10. MyBatis DAO层开发——Mapper动态代理方式