C++类有继承时,析构函数必须为虚函数。如果不是虚函数,则使用时可能存在内在泄漏的问题。

假设我们有这样一种继承关系:

如果我们以这种方式创建对象:

SubClass* pObj = new SubClass();
delete pObj;

不管析构函数是否是虚函数(即是否加virtual关键词),delete时基类和子类都会被释放;

如果我们以这种方式创建对象:

  • 若析构函数是虚函数(即加上virtual关键词),delete时基类和子类都会被释放;
  • 若析构函数不是虚函数(即不加virtual关键词),delete时只释放基类,不释放子类;
  • 测试代码

    大家可以自己测试一下,以下是我的测试代码:

    #include <string>
    #include <iostream> class BaseClass
    {
    public:
    BaseClass()
    : m_pValue(NULL)
    {
    } /*virtual */~BaseClass()
    {
    delete m_pValue;
    m_pValue = NULL;
    std::cout << "BaseClass virtual construct." << std::endl;
    } void SetValue(int v)
    {
    if (!m_pValue)
    {
    m_pValue = new int(v);
    }
    else
    {
    *m_pValue = v;
    }
    } private:
    int* m_pValue;
    }; class SubClass : public BaseClass
    {
    public:
    SubClass()
    : BaseClass()
    , m_pstrName(NULL)
    {
    } /*virtual */~SubClass()
    {
    delete m_pstrName;
    m_pstrName = NULL;
    std::cout << "SubClass virtual construct." << std::endl;
    } void SetName(const std::string& name)
    {
    if (!m_pstrName)
    {
    m_pstrName = new std::string(name);
    }
    else
    {
    *m_pstrName = std::string(name);
    }
    } private:
    std::string* m_pstrName;
    }; int main()
    {
    BaseClass* pObj = new SubClass();
    pObj->SetValue();
    ((SubClass*)pObj)->SetName("zhangsan");
    delete pObj;
    pObj = NULL;
    return ;
    }

    原文地址:https://blog.csdn.net/luoweifu/article/details/53780438

C++类有继承时,析构函数必须为虚函数的更多相关文章

  1. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  2. (C++)浅谈多态基类析构函数声明为虚函数

    主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...

  3. C++多态性中基类析构函数声明为虚函数

    在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...

  4. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  5. 读书笔记 effective c++ Item 36 永远不要重新定义继承而来的非虚函数

    1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf.Mf的参数和返回类型并不重要,所以假设它们都是void. ...

  6. C++进阶--构造函数和析构函数中的虚函数

    //############################################################################ /* 任何时候都不要在构造函数或析构函数中 ...

  7. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  8. C++中为什么要将析构函数定义成虚函数

    构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个 ...

  9. C++析构函数定义为虚函数(转载)

    转载:http://blog.csdn.net/alane1986/article/details/6902233 析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数.如果析构函数不是虚函 ...

随机推荐

  1. (32)forms组件(渲染自建规则:局部钩子函数和全局钩子函数)

    要达成渲染自建规则 1.局部钩子函数(某个字段,自定意义规则,不如不能以sb开头,数据库已存在等) 2.全局钩子函数(校验两次密码是否一致) 3.使用css样式 register.html <! ...

  2. javascript常见的几种事件类型

    第一种事件类型:onchange() <body> <select id="sheng" onchange="fn1();"> < ...

  3. 远程桌面连接问题,ping服务器ip无法连接主机。

    今天是礼拜一,上班的第一天去连公司的服务器,远程桌面竟然登录不上. 试了一下同事的电脑,也是一样的情况无法连接到远程计算机.这下可把我急坏了. 试了很多方法,也重新启动了服务器,重启后同事的win10 ...

  4. Linux中“零拷贝”

    服务器响应一个http请求的步骤 把磁盘文件读入内核缓冲区 从内核缓冲区读到内存 处理(静态资源不需处理) 发送到网卡的内核缓冲区(发送缓存) 网卡发送数据 数据从第一步中的内核缓冲区到第四步的内核缓 ...

  5. 第三章 C#程序结构(3.1 顺序与选择结构)

    [案例]输入某一学生的成绩,输出其对应的档次.具体规定:90分以上为优秀,80分以上至89分为良好,70分至79分为一般,60分至69分为合格,59以下为不及格.如果输入的分数小于0或大于100,则输 ...

  6. 解决centos 7.5安装openvpn,mirrors.163.com提示没有可用软件包openvpn、easy-rsa问题

    提示: yum install openvpn 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * base: mirro ...

  7. [ZZ] UIUC同学Jia-Bin Huang收集的计算机视觉代码合集

    UIUC同学Jia-Bin Huang收集的计算机视觉代码合集 http://blog.sina.com.cn/s/blog_4a1853330100zwgm.htmlv UIUC的Jia-Bin H ...

  8. Java多态(非常重要)

    多态(多种形态)的定义 同一消息对不同类的对象做出的不同响应 种类 在程序设计中一般说多态都是运行时多态 多态施行的条件: 1满足继承关系 2父类引用指向子类对象(向上转型) 向上转型 向下转型(子类 ...

  9. finstrument-functions

    2017-12-03 23:59:16 参考 如何快速地在每个函数入口处加入相同的语句? https://www.zhihu.com/question/56132218 做个存档 scj@scjCom ...

  10. 用GDB调试程序(三)

    四.维护停止点 上面说了如何设置程序的停止点,GDB中的停止点也就是上述的三类.在GDB中,如果你觉得已定义好的停止点没有用了,你可以使用delete.clear.disable.enable这几个命 ...