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++开发的时候,用来做基类的类的析构函数一般都是虚函数。可是,为什么要这样做呢?下面用一个小例子来说明:        有下面的两个类:class ClxBase{public:...
  • starlee
  • starlee
  • 2006年03月09日 15:34
  • 153146

为什么基类的析构函数要声明成虚函数

原因: 在公有继承中,基类的虚构函数如果不声明成为虚函数,那么销毁派生类时有可能造成资源泄漏 class Base{ public:         Base( ) {   };       ~Bas...
  • ljlstart
  • ljlstart
  • 2015年10月21日 22:03
  • 1529

析构函数是否必须为虚函数?什么情况下才应该定义析构函数为虚函数?

多态是面向对象的一个基本属性,包括静态多态(编译阶段)和动态多态(运行阶段),静态多态主要是指函数参数不同产生的多态性,是在编译阶段可以识别的一种多态机制,而运行时多态则主要用于基类指针指向派生类对象...
  • zhangqk2016
  • zhangqk2016
  • 2016年07月07日 11:02
  • 1054

C++ 析构函数

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

C++中多个类继承时构造函数与析构函数的调用顺序

#include using namespace std; /**  c++多个类之间继承,但是不能继承(构造函数,析构函数)  构造函数,析构函数只能有基类来调用,创建对象调用顺序:父类->...
  • pangqiandou
  • pangqiandou
  • 2017年03月09日 21:47
  • 629

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

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

C++中析构函数为虚函数时调用发生了什么变化

昨天去XX公司面试,面试官问了一个关于C++类析构函数为虚函数时,如果是父类的指针用子类来new,如果发生析构时,析构函数是virtual与不是virtual有什么区别。当时答的不好,回来总结了一下,...
  • fenghaibo00
  • fenghaibo00
  • 2011年08月16日 18:20
  • 2687

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

解析函数要 virtual #include using namespace std; class CBase { public: CBase(int i){ m_data = i;cout ...
  • u012543266
  • u012543266
  • 2013年11月03日 20:43
  • 1960

基类析构函数必须为虚函数否则会造成内存泄漏

看看下面程序有什么错误: #include using namespace std; class Father { public: Father(){}; ~Father...
  • asd199086
  • asd199086
  • 2016年08月14日 20:39
  • 1902

关于析构函数和纯虚函数

之前一直不知道,虚析构函数yo
  • guozhengdong
  • guozhengdong
  • 2014年09月29日 22:18
  • 1015
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++类有继承时,析构函数必须为虚函数
举报原因:
原因补充:

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