(整理自Effctive C++,转载请注明。整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/

这个规则只适用于polymorphic(带多态性质的)base class身上。这种base class的设计目的是为了用来“通过base class接口处理derived class对象”。假如我们在程序中设计factory(工厂)函数,让它返回base class指针,指向新生成的derived class对象,假设base class有个non-virtual析构函数,当derived class对象经由一个base class

指针被删除,其结果未定义——实际执行时通常发生的是对象的derived成分没有被销毁,然而其base class成分通常会被销毁,造成一个诡异的“局部销毁”对象。

消除这个问题的做法很简单:给base class一个virtual析构函数。此后删除derived class对象就会如你想要的那般。是的,它会销毁整个对象,包括所有的derived class成分:

   1: class TimeKeeper{

   2: public:

   3:     TimeKeeper();

   4:     virtual ~TimeKeeper(); //将多态基类的析构函数声明为virtual

   5:     ...

   6: };

   7:  

   8: TimeKeeper* ptk = getTimeKeeper(); //返回一个指针,指向一个TimeKeeper派生类的动态分配对象

   9: ...

  10: delete ptk ; 

像TimeKeeper这样的base class除了析构函数之外通常还有其他virtual函数,因为virtual的目的是允许derived class的实现得以客制化。任何class只要带有virtual函数都几乎确定也应该有一个virtual析构函数 。

如果class不含virtual函数,通常表示它并不意图被用作一个多态性的base class。当class不企图被用作多态性的base class,令其析构函数为virtual往往是个馊主意。

因此:无端地将所有classes的析构函数声明为virtual,就像从未声明它们为virtual一样,都是错误的。正确做法:只有当class内含至少一个virtual函数,才为它声明virtual析构函数。

有时候令class带有一个pure virtual析构函数颇为便利。如果你需要你一个abstract classes,令析构函数为 pure virtual,不仅为你提供一个pure virtual 函数,让你得到一个抽象类,而且析构函数为virtual,删除派生类对象时也不会出问题。然而这里有个窍门:你必须为这个pure virtual析构函数提供一份定义。析构函数的运作方式:最深层派生的那个class其析构函数最先被调用,然后是其每一个base class的析构函数被调用。编译器会在derived class的析构函数中创建一个对base class析构函数的调用动作,所以你必须为这个函数提供一份定义。

请记住:

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

(2)class的设计目的如果不是作为base classes使用,或不是为了具备多态,就不应该声明virtual析构函数。

Effective C++_笔记_条款07_为多态基类声明virtual析构函数的更多相关文章

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

    class TimeKeeper { public: TimeKeeper(); // ~TimeKeeper(); 错误,此作为一个基类,被继承了.其继承类被delete后,基类被销毁,但继承类可能 ...

  2. 《effective C++》:条款07——为多态基类声明virtual析构函数

    在继承中,基类的析构函数需要定义为虚析构函数数否则: (1)当派生类对象经由一个base类指针删除时,而这个base类的析构函数不是虚函数时,其结果是未定义的. (2)这样做会导致derived类部分 ...

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

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

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

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

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

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

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

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

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

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

  8. [Effective C++系列]-为多态基类声明Virtual析构函数

    Declare destructors virtual in polymorphic base classes.   [原理] C++指出,当derived class对象经由一个由base clas ...

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

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

随机推荐

  1. Oracle同义词 synonyms

    Oracle中的同义词: 总结:简单的一句话,Oracle中不同用户的表一般都只能够自己的所属的用户可以用,如果不想通过授权的方式授权给其他用户使用,那么创建表的时候在表名的前面加上 synonyms ...

  2. line

    小君童靴说头儿给了他一个project,实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点.觉得这个很好玩,就自己也写了一点code /* date : 2014/10/21 version ...

  3. ASP.NET MVC 5 学习教程:创建连接字符串

    原文 ASP.NET MVC 5 学习教程:创建连接字符串 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...

  4. spring mvc 和ajax异步交互完整实例

    Spring MVC 异步交互demo: 1.jsp页面: <%@ page language="java" contentType="text/html; cha ...

  5. 一步一步重写 CodeIgniter 框架 (11) —— 使用 CodeIgniter 函数库

    在完成了CI框架的类库扩展后,很自然我们就会想到函数库的扩展.函数库的扩展在 CI 中称为 helper 函数与类有不同的地方,它不能继承,只能覆盖或者添加新的函数,或者直接完全新定义的一组函数. 由 ...

  6. WinForm----DataGridview---连接数据库,以及双击一条数据,显示信息到Label控件,也可以是TextBox控件。

    最终效果: 代码: using System; using System.Collections.Generic; using System.ComponentModel; using System. ...

  7. sourceinsight 相对路径设置

    1. mkdir sin(source insight prj dir) 2. creat sin prj 3. push OK directly without setting source fil ...

  8. 使用Spring标签库

    A.Spring标签库 Web项目若使用Spring Web MVC并使用JSP作为表现的话.从Spring2.0版本开始提供一套标签库可供使用. 使用标签库无非是易于开发,维护之类云云.这里就不阐述 ...

  9. 基于visual Studio2013解决C语言竞赛题之0806平均分

     题目

  10. What’s new in Spark 1.2.0

    What's new in Spark 1.2.0 1.2.0 was released on 12/18, 2014 在2014年5月30日公布了Spark 1.0 和9月11日公布了Spark1. ...