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. python要开始记录了20181125

    print('1.使用while循环输入 1 2 3 4 5 6 8 9 10') i = 1 while i < 10: i += 1 if i == 7: continue #print(' ...

  2. python: ImportError:DLL load failed 解决方法。

    在学习使用wordcloud 库创建词云过程中,mooc里提到可以使用另一个库函数,来创建不同形状的词云. 就是这句: ... from scipy.misc import imread mk = i ...

  3. APK重编译

    最近沉迷某游戏 尝试了一些不可描述的东西 , 记录一下研究过程 具体是哪个app不公开 ... 准备工具 APKtool && signapk && jre .net ...

  4. day11 大纲

    01 昨日内容回顾 函数名的运用: 1,特殊的变量. 2,函数名可以当做变量赋值. 3,函数名可以当做容器类类型的元素. 4,函数名可以当做函数的参数. 5,函数名可以当做函数的返回值. 函数的运用: ...

  5. liunx top命令详解

    1,当前服务器时间,up,服务器离上一次重启过了多久,多少个用户在使用,cpu平均负载,grep 'core id' /proc/cpuinfo | sort -u | wc -l  ,一般来说4个, ...

  6. [转]c++访问python3-实例化类的方法

    转自: http://blog.csdn.net/love_clc/article/details/76653100 此文是学习笔记,供日后翻阅.下面列出C++访问python所需的函数,按调用的先后 ...

  7. string formating字符串格式化,function函数,group组,recursion递归,练习

    # -*- coding: UTF-8 -*- msg = 'i am {} my hobby is {}'.format('lhf',18) print(msg) msg1 = 'i am %s m ...

  8. TCP/IP学习20180701-数据链路层-IP子网寻址

    IP-子网寻址IP地址是:网络号+主机号现在主机号都要求有子网号所以IP地址就变成了网络号+子网号+主机号例如一个B类地址:210.30.109.134210.30是网络号109是子网号134是主机号 ...

  9. UML 序列图详解

    现在是二月,而且到如今你或许已经读到.或听到人们谈论UML 2.0 —— 包括若干进步的 UML 的新规范,所做的变化.考虑到新规范的重要性,我们也正在修改这个文章系列的基础,把我们的注意力从 OMG ...

  10. google的protobuf简单介绍

    google的protobuf是一种轻便高效的结构化数据存储格式,在通信协议和数据存储等领域中使用比较多.protobuf对于结构中的每个成员,会提供set系列函数和get系列函数. 但是,对于使用来 ...