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++ 析构函数

C++ 析构函数我使用的继承开发环境: Visual Studio 2010设计一个类时,如何写析构函数? 析构函数如果我们不写的话,C++ 会帮我们自动的合成一个,就是说:C++ 会自动的帮我们...

c++继承中析构函数的调用顺序

在继承中的析构函数主要遵从一下四点规则: 1、首先调用派生类的析构函数(清理派生类的新增成员) 2、如果派生类中有子对象 , 则再调用派生类中子对象的析构函数 , 调用顺序是:在派生类中,先定义后...

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

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

C++ 构造函数和析构函数是否可以继承?

先看一个例子: [cpp] view plaincopy #include       class A   {   public: ...

C++继承之构造析构函数调用

虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的.最派生类是指在继承结构中建立对象时所指定的类.在派生类的构造函数的成员初始化列表中,必须列出对虚基类构造函数的调用,如果没有列出...

C++ 为什么设置基类的析构函数为虚函数

对象的析构函数调用顺序是从派生类到基类 那么如果基类的指针指向派生类的对象 还能正常的执行析构顺序吗 下面看一个类的声明 [cpp] view pla...

C++虚函数和纯虚函数和抽象类

C++虚函数和纯虚函数和抽象类分析
  • x_r_su
  • x_r_su
  • 2016年08月31日 13:31
  • 595

C++中虚析构函数的作用

    我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。可是,为什么要这样做呢?下面用一个小例子来说明:        有下面的两个类:class ClxBase{public:...
  • starlee
  • starlee
  • 2006年03月09日 15:34
  • 148349

为什么构造函数不能声明为虚函数,析构函数可以

构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。 不建议在构造函数和析构函数里面调用虚函数。 构造函数不能声明为虚函数的原因是: 1 构造一个对象的时候,必须...

MYSQL 的几种join连接方式

一、关于JOIN语法【内容来自于mysql手册】 MySQL支持以下JOIN语法。这些语法用于SELECT语句的 table_references 部分和多表DELETE和UPDATE语句: tabl...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++类有继承时,析构函数必须为虚函数
举报原因:
原因补充:

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