2010.7.29 为什么析构函数设计成虚函数?
首先必须明白,声明成虚函数,必须是在有继承关系的几个类中,才有意义。
当声明了一个基类(CBase),和一个继承类时(CSubDevice::CBase)时,基类有自己的成员需要用析构释放内存,继承类也有自己的成员需要释放内存。
如何用一个基类的指针,指向了一个子类的对象,那么当释放基类指针指向的堆内存时,假如这时候析构函数没有使用虚函数,那么程序只会调用基类的析构函数,这时,子类的特有的内存没有释放,造成了内存泄漏。
如下:
class CDevice
{
public:
CDevice(void);
public:
~CDevice(void);
};
class CBase
{
public:
CBase(void);
public:
~CBase(void);
public:
CDevice* pDevice;//需要在析构中释放 1
};
class CSubDevice:public CBase
{
public:
CSubDevice(void);
public:
~CSubDevice(void);
public:
CString *pCstr; //需要在析构中释放 2
};
假如有这样一个对象:
CBase* pBase=new CSubDevice();
那么释放的时候,即Delete pBase时,只调用了~CBase(), 2处没有调用造成了内存泄漏(pCstr没有被释放)
怎么解决呢?
假如定义~CBase(void);
为虚函数,即Virtual ~CBase(void),如下
class CDevice
{
public:
CDevice(void);
public:
~CDevice(void);
};
class CBase
{
public:
CBase(void);
public:
Virtual ~CBase(void);
public:
CDevice* pDevice;//需要在析构中释放 1
};
class CSubDevice:public CBase
{
public:
CSubDevice(void);
public:
Virtual ~CSubDevice(void);
public:
CString *pCstr; //需要在析构中释放 2
};
在这种情况下,如下:
CBase* pBase=new CSubDevice();
那么释放的时候,即Delete pBase时,不仅调用了~CBase,还调用了~CSubDevice。实际上是先调用了~CSubDeivce,然后调用了~CBase;
如果是CSubDevice* pBase=new CSubDevice();
那么释放的时候,即 Delete pBase时,先调用了~CSubDeivce,然后调用了~CBase;
在以上两种情况下,不管~CSubDevice中有没有代码,都会被调用,哪怕是空的函数体。
如果是CBase* pBase=new CBase()呢?
只会调用~CBase()

浙公网安备 33010602011771号