C++类有继承时,析构函数必须为虚函数

原创 2016年12月21日 09:24:14

虚函数与多态一文中讲了虚函数的用法和要点,但少讲了一点,就是虚函数在析构中的用法,本文就是修复一bug的。

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

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


类的继承关系

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

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

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

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

BaseClass* pObj = new SubClass();
delete pObj;
  • 若析构函数是虚函数(即加上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(10);
    ((SubClass*)pObj)->SetName("zhangsan");
    delete pObj;
    pObj = NULL;
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得用于任何商业用途,转载请注明出处。

相关文章推荐

C++继承类中析构函数的问题

解析函数要 virtual #include using namespace std; class CBase { public: CBase(int i){ m_data = i;cout ...

CString与string、char*的区别和转换

我们在C++的开发中经常会碰到string、char*以及CString,这三种都表示字符串类型,有很多相似又不同的地方,常常让人混淆。下面详细介绍这三者的区别、联系和转换: 各自的区别 char...

带你玩转Visual Studio——带你发布自己的工程库

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。比如你经常使用的STL(Standard Template L...

带你玩转Visual Studio——带你跳出坑爹的Runtime Library坑

Windows下**C Runtime Library**是微软对C标准库函数的实现,这样每个程序可以直接使用C标准库的函数;后来出现了C++,于是又在C Runtime Library基础上开发了*...

freemarker 在ftl页面通过#list 获取后台存入map值并放去select的option中

项目采用SpringMVC+MyBatis 框架。        页面显示下拉选项框select中的信息(option),是用字符串类型的参数“1.AA,2.BB,3.CC”维护起来,以后修改参数就...

form:select 使用总结

今天在做项目的时候发现需要用到下拉框,但是本人又不想写成固定的select框,所以只好找找有没有可以自动填充的下拉列表框 我记得做struts2项目的时候有个S:select标签,但是那个标签必须经...
  • TOP_Y
  • TOP_Y
  • 2016-09-01 10:41
  • 13865

C++继承中的虚析构函数

看看下面程序有什么错误: #include using namespace std; class Father { public: Father(){}; ~Father...

Eclipse无法识别(手机)设备的解决方案

遇到问题 开始学习android一个多月了,用Eclipse开发,用android手机调试。之前一直好好的,突然Eclipse无法识别手机设备了。纠结了好久,找了各种解决方法,弄了一晚上终于解决问题了...

解决eclipse不识别Android手机--ADB 无法检测到手机

在打开了开发者模式,更换了数据线,重启了Eclipse以后仍然无法检测到设备。 于是打开命令行,进入adb.exe所在文件夹,直接使用adb(输入adb devices),发现不能列出设备: ...

让Visual Studio 调用Matlab的扩展

1、首先你得有matlab的扩展库,不如安装一个matlab。2、其次,打开Visual Studio,在"工具">"选项"中的"项目和解决方案"中的"VC++目录",然后设置:包含文件:MATLAB...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)