真正理解虚析构函数

在我真正理解虚析构函数之前,差不多每隔一个月,我都要百度一下“虚析构函数的作用”。因为我在写一个类时,总是不能确定是否应该将其析构函数写为虚函数。直到某一天,我突然地就悟了。

事实上,虚析构函数,就是析构函数,也就是析构函数具有了虚函数的性质。

有如下代码:

class CBase
{
public:
    CBase() { m_pArray = new int[20]; }
    ~CBase() { delete [] m_pArray; }
private:
    int* m_pArray;
};

class CDerived : public CBase
{
public:
    CDerived() { m_pBuffer = new char[20]; }
    ~CDerived() { delete [] m_pBuffer; }
private:
    char* m_pBuffer;
};

int main()
{
    CBase* pBase = new CDerived;
    delete pBase; // pBase->~CBase()
    return 0;
}

我们知道,delete会触发类的析构函数,一定程度上,我们可以把它当做调用类的析构函数。那么delete pBase就相当于pBase->~CBase(),此时调用的是CBase::~CBase(),而CDerived::~CDerived()未被调用,这造成了m_pBuffer的内存泄漏。

为了解决这个问题,我们可以设置CBase析构函数虚函数。由于虚函数多态性pBase->~CBase()实际调用的就会是CDerived::~CDerived(),而CDerived::~CDerived()又会调用CBase::~CBase()。所有的析构函数都被调用了,就不再有内存泄漏发生了。

解决因delete基类指针导致的资源泄漏,这就是虚析构函数的作用所在;而具有虚函数性质的析构函数,这就是虚析构函数的真相所在。

下面两幅图应该可以帮助你更好地理解:


真正理解虚析构函数_第1张图片
普通析构函数与虚析构函数

你可能感兴趣的:(真正理解虚析构函数)