作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的。因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性。   这个类可能会被继承,并且会通过基类的指针指向子类对象”,因此基类的析构函数是否为虚将决定子类的对象是否被析构

示例代码:

#include <iostream.h>

struct A
{
virtual ~A() {cout<<"~A()\n";}
}; struct B: public A
{
~B() {cout<<"~B()\n";}
}; void main()
{
A* p = new B;
delete p;
}

如果 A的析构函数不是virtual的,那么此时就不是先调用B的析构函数再调用A的析构函数。 
Output:
~A();  
如果A   的析构函数为virtual,则先~B(),再~A()   
Output:
~B();
~A();
       类如果会被派生的话,析构函数一般都应该定义为virtual的,主要不是防止内存泄露,而是为了正确的析构。如果是个封闭类(即不再被派生),就不要定义为virtual的。虚函数毕竟耗费较大的。

不用virtual 的几种情况:
  1、作为非公有基类。仅作为   private   base   class   使用的   class   不需要使用虚拟析构函数   
  2、不作为接口使用的基类。   
  3.   如果你可以保证这个类不被public继承(private/protected继承的话,在非friend函数/类中就无法用基类指针指向派生类了)   
  4.   如果它的所有派生类(包括派生类的派生类)的析构函数都是trivial的(这里的trivial指的是在程序员的层次什么事也不做)   
  5.   如果不需要用基类的指针指向派生类的对象   
  在这五种情况下,不把析构函数声明为virtual都是可以的,何况效率会高一些——但前提是你得保证前提的成立——不过这些保证常常是很难100%的:谁能保证别人在派生你的类的时候,析构函数是trivial的,或者别人不用你提供的基类的指针指向派生类对象?这些常常是很难得到保证的。

声明基类的析构函数为virtual并非总是为了防止memory   leak   另外这也只是作为一般的原则(基类中有虚函数则把其析构函数声明为virtual)。如果你的析构函数什么事也不作,从效果上来说,不声明为virtual也无妨.

析构函数virtual与非virtual区别 [转]的更多相关文章

  1. C++-基类的析构函数为什么要加virtual虚析构函数(转)

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

  2. C#中virtual与abstract的区别

    C#中virtual与abstract的区别 C#的virtual & abstract经常让人混淆,这两个限定词都是为了让子类进行重新定义,覆盖父类的定义.但是用法上差别很大. a)     ...

  3. asp.net中virtual和abstract的区别

    这篇文章主要介绍了asp.net中virtual和abstract的区别,较为详细的分析了virtual与abstract的概念与具体用法,并以实例的形式予以总结归纳,需要的朋友可以参考下 本文实例分 ...

  4. asp.net中virtual和abstract的区别分析

    这篇文章主要介绍了asp.net中virtual和abstract的区别,较为详细的分析了virtual与abstract的概念与具体用法,并以实例的形式予以总结归纳,需要的朋友可以参考下 本文实例分 ...

  5. C#中virtual和abstract的区别

    先说区别: virtual意思是虚拟,abstract意思是抽象. virtual只修饰方法,abstract修饰方法和类. virtual方法必须有实现,abstract方法必须没有实现. publ ...

  6. 【C++】C++中基类的析构函数为什么要用virtual虚析构函数?

    正面回答: 当基类的析构函数不是虚函数,并且基类指针指向一个派生类对象,然后通过基类指针来删除这个派生类对象时,如果基类的析构函数不是虚析构函数,那么派生类的析构函数就不会被调用,从而产生内存泄漏 # ...

  7. c++ virtual 和 pure virtual的区别

    参考资料: http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained 验证代码: #include < ...

  8. 析构函数和Dispose的使用区别

    老生常谈的问题了,MSDN也有非常详细的说明但看起来不是很系统.也曾经做过分析,但没有总结下来又忘了,这次整理一下MSDN和网上搜集的一些资料,以备不时只需. 下面是MSDN对这两个函数的建议使用方法 ...

  9. IO多路复用,同步,异步,阻塞和非阻塞 区别

    一.什么是socket?什么是I/O操作? 我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已,不管socket,还是FIFO.管道.终端,对我们来说,一切都是 ...

随机推荐

  1. jQuery ClockPicker 圆形时钟

    ClockPicker.js是一款时钟插件,其实还可以改进,里面的分可以改成短横线. 在线实例 实例预览  jQuery ClockPicker 圆形时钟 使用方法 <div class=&qu ...

  2. Sublime Text 3 快捷键精华版

    Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+V:粘贴并格 ...

  3. SVN版本控制系统学习(中文配置)

    先吐槽下往上搜索的一些SVN下载地址,里面乱七八糟啥都有,下载好后点击安装一不注意啥玩意都安装上了, 什么玩意都有,真心不明白这些推送者是怎么想的.搜集了一个WIN32的百度网盘下载地址: http: ...

  4. c#使用json接口

    前些日子将项目由使用数据库改版为使用接口,由于接口返回的xml中多了一些附加信息,导致xml转化后的DataTable无法储存在MemCache中.这时可以将xml序列化为其对应的类,当然由于当时对x ...

  5. 原生JS:JSON对象详解

    JSON对象 支持到IE8,旧版的IE需要Polyfill 本文参考MDN做的详细整理,方便大家参考[MDN](https://developer.mozilla.org/zh-CN/docs/Web ...

  6. 64位win7+vs2010编译.net3.5以前的版本问题

    一般编译会出现 1.“ResGen.exe”已退出,代码为2 问题处理 2.“错误 2 “LC.exe”已退出,代码为 -1. NBGIS.MainGIS” 3.“未能加载文件或程序集“ESRI.Ar ...

  7. Java泛型介绍——HashMap总结

    今天在编程中,需要使用到Hashmap来存储和传递数据,发现自己学习Java这么久,实际上对泛型依旧知之甚少,搜索整理了一下HashMap的使用. HashMap的声明初始化,因为泛型的原因,起两个参 ...

  8. 用MSF进行提权

    在WEB渗透中当我们拿到webshell了,我们可以试试用MSF(metasploit)来进行提权,在MSF里meterpreter很强大的! 我们先用msfvenom生成一个EXE的木马后门. ms ...

  9. 视图xsl定制之嵌入服务器控件

    SharePoint 2010 视图 xsl 文件中支持嵌入服务器控件,嵌入服务器控件时,系统先采用xsl将视图xml解析成一个类似UserControl的存在,然后执行UserControl. 代码 ...

  10. 实现Discuz论坛客户端应用源码

    通过使用该源码,开发者可以迅速地将Discuz论坛迁移到Android客户端中.不需要任何的开发工作即可拥有属于自己论坛的Android客户端 源码下载:http://code.662p.com/vi ...