一个函数的返回值为基类指针,而当指针指向一个派生类对象,接下来派生类对象被这个基类指针删除的时候,就出现了局部销毁的问题。因为C++指出,当派生类经由一个基类指针被删除,而该基类指针带着一个non-virtual析构函数,其结果未有定义。实际的执行情况是派生类的析构函数没有执行,然而基类的成分通常会被销毁,于是早晨了诡异的“局部销毁”对象。这是造成资源泄漏、败坏数据结构、在调试器上浪费许多时间的绝佳途径==。

给基类一个virtual析构函数就可以消除这个问题了。

如果基类不含virtual函数,通常表示它并不意图被用做一个基类,当class不企图被当作基类时,令其析构函数为virtual往往是个馊主意。某些不带virtual函数的小型类本可以当作参数传给C语言的函数,但是如果把析构函数变成virtual,会增加类的大小,因为有了虚函数,类会有vtbl(virtual table虚函数表),一个 由函数指针组成的数组,这个函数指针是vptr(virtual
table pointer)指针,在运行期指出哪一个virtual函数该被调用。

有时候令class带一个pure virtual析构函数(纯虚析构函数)可能会带来一些便利。纯虚函数导致抽象类,不能被实体化。有时候希望拥有抽象类,但没有纯虚函数,策略就是:为你希望它成为抽象类的哪个class声明一个纯虚析构函数;还有一点注意就是要给这个纯虚析构函数一个定义,因为析构函数的运作方式是最深层派生的类的析构函数最先被调用,然后每一个基类的析构函数被调用。编译器会在派生类的析构函数中创建一个对抽象基类析构函数的调用动作,所以你必须为这个函数提供一份定义。

总结:

1、polymorphic(带多态性质的)基类应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。

2、Calsses的设计目的不是作为基类使用(例如标准string和STL容器),或不是为了具备多态性(polymorphically),就不该声明virtual析构函数。

为多态基类声明virtual析构函数的更多相关文章

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

    C++明确指出:当派生类对象是由一个基类指针释放的,而基类中的析构函数不是虚函数,那么结果是未定义的.其实我们执行时其结果就是:只调用最上层基类的析构函数,派生类及其中间基类的析构函数得不到调用. # ...

  2. [Effective C++ --007]为多态基类声明virtual析构函数

    引言: 我们都知道类的一个很明显的特性是多态,比如我们声明一个水果的基类: class Fruit { public: Fruit() {}; ~Fruit(){}; } 那么我们根据这个Fruit基 ...

  3. effective c++(07)之为多态基类声明virtual析构函数

    class TimeKeeper { public: TimeKeeper() ; ~TimeKepper() ; ... } ; class AtomicClock:public TimeKeepe ...

  4. Effective C++_笔记_条款07_为多态基类声明virtual析构函数

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 这个规则只适用于polymorphic(带多态性质的)base ...

  5. 【C++】为多态基类声明virtual析构函数

    来自<Effective C++>条款07:为多态声明virtual析构函数 当derived class对象经由一个base class指针被删除,而该base class带着一个non ...

  6. NO.6: 为多态基类声明virtual析构函数

    注意:polymorphic base class 应该具有虚析构函数,如果class带有任何virtual函数,也应具有虚析构函数 class不具备polymorphic属性则不应该声明virtua ...

  7. Effective C++(7) 为多态基类声明virtual析构函数 or Not

    问题聚焦: 已经对一个对象执行了delete语句,还会发生内存泄漏吗? 先来看个demo: // 计时器类 class TimeKeeper { public: TimeKeeper(); ~Time ...

  8. Effective C++ -----条款07:为多态基类声明virtual析构函数

    polymorphic(带多态性质的)base classes应该声明一个virtual析构函数.如果class带有任何virtual函数,它就应该拥有一个virtual析构函数. Classes的设 ...

  9. Effective C++学习笔记 条款07:为多态基类声明virtual析构函数

    一.C++明确指出:当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未定义——实际执行时通常发生的是对象的 ...

随机推荐

  1. TensoFlow实现条件语句

    import tensorflow as tf a = tf.constant(20) b = tf.constant(10) result1 = tf.cond(a > b, lambda: ...

  2. 一个数组保存了N个结构,每个结构保存了一个坐标,结构间的坐标都不相同,请问如何找到指定坐标的结构(除了遍历整个数组,是否有更好的办法)?

    #include <iostream> #include <map> using namespace std; #define N 5 typedef struct point ...

  3. Linux for sougou ping yin (http://pinyin.sogou.com/linux/help.php)

    安装指南 Ubuntu / Ubuntu Kylin 14.04 LTS 版本 只需双击下载的 deb 软件包,即可直接安装搜狗输入法. Ubuntu 12.04 LTS 版本 由于 Ubuntu 1 ...

  4. 19 Handler 总结

    Handler 一, 回顾异步任务 AsyncTask 二, android 使用线程的规则 1,在主线程 不能做阻塞操作 2,在主线程之外的线程不能更新Ui 三, Handler的作用 1,在子线程 ...

  5. 程序员的自我修养-----Java开发的必须知道的几个注意点

    1. 将一些需要变动的配置写在属性文件中 比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置.那么你的程序无论在DEV环境中,还是TEST环境中,都可以顺畅无阻地运行,但是一旦部署在P ...

  6. DOM4J生成、解析XML实例

    import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Iterato ...

  7. #VSTS日志# Xamarin构建支持和一大波更新

    距离上次更新#VSTS日志#已经有将近3个月的时间了,赶上最近Xamarin开源免费的消息,VSTS也推出了更多跨平台的支持和许多其他功能.这里列出一些小编觉得比较重要. 1. Xamarin 构建模 ...

  8. Socket层实现系列 — send()类发送函数的实现

    主要内容:socket发送函数的系统调用.Socket层实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 发送流程图 以下是send().sendt ...

  9. 【移动开发】Service类onStartCommand()返回值和参数

    Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStart ...

  10. 使用Spring+Junit4.4进行测试

    http://nottiansyf.iteye.com/blog/345819 使用Junit4.4测试 在类上的配置Annotation @RunWith(SpringJUnit4ClassRunn ...