C++ Primter中讲“在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数”。

析构函数是为了在对象不被使用之后释放它的资源,虚函数是为了实现多态。那么把析构函数声明为vitual有什么作用呢?,下面通过例子来说明一下vitual的用途。

using namespace std;

class Base
{
public:
  Base() {};     //Base的构造函数
  ~Base()        //Base的析构函数
  {
    cout << "the destructor of class Base!" << endl;
  };
  virtual void DoSomething() 
  {
    cout << "Do something in class Base!" << endl;
  };
};
    
class Derived : public Base
{
public:
  Derived() {};     //Derived的构造函数
  ~Derived()      //Derived的析构函数
  {
    cout << "the destructor of class Derived!" << endl;
  };
  void DoSomething()
  {
    cout << "Do something in class Derived!" << endl;
  };
};
    
int main()
{
  Derived *pTest1 = new Derived();   //Derived类的指针
  pTest1->DoSomething();
  delete pTest1;
    
  cout << endl;
    
  Base *pTest2 = new Derived();      //Base类的指针
  pTest2->DoSomething();
  delete pTest2;
    
  return 0;
}

先看程序输出结果:
1       Do something in class Derived!
2       the destructor of class Derived!
3       the destructor of class Base!
4      
5       Do something in class Derived!
6       the destructor of class Base!

从运行结果来看,pTest1运行比较正常,也好理解,pTest2运行了子类的Do something和父类的析构函数,并没有运行子类的析构函数,这样会造成内存泄漏。

pTest2运行了子类的Do something量因为父类的Do something加了virtual。

pTest2运行了父类的析构函数是因为父类的析构函数并没有加virtual,所以它并不会运行子类的析构函数。

如果Base的析构函数加上virtual,那么pTest1和pTest2运行过程一样。

总结:如果一个类有可能会被继承,那么它的析构函数最好加上virtual,不然出现内存泄漏问题找都找不到。

virtual析构函数的作用的更多相关文章

  1. Effective C++ .07 virtual析构函数的提供

    主要讲了, 1. virtual析构函数的作用与调用顺序 2. 使用时机,并不是使用了继承就要把基类的析构函数变为虚函数(virtual),只有当用于多态目的时才进行一个virtual析构函数的定义. ...

  2. C++ 构造函数和析构函数的调用顺序、虚析构函数的作用

    构造函数和析构函数的调用顺序 构造函数的调用顺序: 当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达最底层的目标派生类的构造函数为止. 析构函数的调用书序: ...

  3. 07——为多态基类声明为virtual析构函数

    当基类确定被继承的时候,析构函数声明为virtual是必须的 当返回的派生类的指针或引用的时候,调用析构函数容易发生内存泄漏 当基类作为抽象类使用,声明pure virtual析构函数 析构函数的顺序 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Lync安装随笔

    使用域管理员权限扩展架构 1.iis角色安装 2.net3.5,消息队列服务器.目录服务集成.桌面体验.AD DS和AD LDS工具(远程服务管理工具中),启用WindowsFirewall服务 3. ...

  2. linux和windows文件名称长度限制

    Linux文件名称的长度限制是255个字符 windows下全然限定文件名称必须少于260个字符,文件夹名必须小于248个字符. linux下文件数.文件夹数.文件名称长度的各种限制 下面測试都是在没 ...

  3. BZOJ 1143: [CTSC2008]祭祀river 最长反链

    1143: [CTSC2008]祭祀river Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...

  4. liveness 生存性/活性

    翻译了两篇,这篇就不翻译了,自己写吧. 对于线程来说除了安全性,我们还应该重视它的生存性(我认为翻译成三个字说着比較顺). 为了保证线程安全,我们往往须要用到同步,可是同步限制了线程的运行,线程必须为 ...

  5. string中find函数的使用

    9.47 编写程序,首先查找string"ab2c3d7R4E6"中的每个数字字符,然后查找其中每个字母字符.编写两个版本的程序,第一个要使用find_first_of,第二个要使 ...

  6. java_jdbc_基本连接池

    MyDataSource实现封装连接池,MyConnection实现connection类,通过代理模式相互调用 package cn.itcast; import java.sql.*; publi ...

  7. How the Kernel Manages Your Memory

    http://duartes.org/gustavo/blog/post/how-the-kernel-manages-your-memory/ After examining the virtual ...

  8. UVA 11021 - Tribles(概率)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=481&page=s ...

  9. [转]Spring数据库读写分离

    数据库的读写分离简单的说是把对数据库的读和写操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力. 主(master)数据库提供写操作,从(slave)数据库提供读操作,其实在 ...

  10. hackerrank Day15: Linked List

    #include <iostream> #include <cstddef> using namespace std; class Node { public: int dat ...