Virtual destruct(虚析构函数)
Virtual destruct(虚析构函数)
面试的时候,我答了虚函数是怎么工作的,但是当面试官问我为什么析构函数的基类一定需要virtual时候,我答的不是太好,所以来总结下
先说结论,当基类的指针指向子类的对象时,如果delete此指针,如果基类没有virtual析构函数,那么调用时只会调用基类的析构函数,而子类的空间未释放。
如以下例子
class BaseClass
{
private:
int *m_Basepointer;
public:
BaseClass() { std::cout << "it's Base Construct!" << std::endl; }
~BaseClass()
{
delete m_Basepointer;
std::cout << "it's Base Deconstruct!" << std::endl;
}
};
class SubClass:public BaseClass
{
public:
SubClass() { std::cout << "it's Sub Construct!" << std::endl; }
~SubClass()
{
std::cout << "it's Sub Deconstruct!" << std::endl;
}
};
int main()
{
BaseClass *p_b = new BaseClass;
delete p_b;
std::cout << "---------------------------------\n";
SubClass *p_s = new SubClass;
delete p_s;
std::cout << "---------------------------------\n";
BaseClass *p_b_s = new SubClass;
delete p_b_s;
std::cin.get();
}
从如上例子可以看出子类的析构函数未被调用,此时造成内存泄露。但是在基类加上virtual后,如下
#include<iostream>
class BaseClass
{
private:
int *m_Basepointer;
public:
BaseClass() { std::cout << "it's Base Construct!" << std::endl; }
virtual ~BaseClass()
{
delete m_Basepointer;
std::cout << "it's Base Deconstruct!" << std::endl;
}
};
class SubClass:public BaseClass
{
public:
SubClass() { std::cout << "it's Sub Construct!" << std::endl; }
~SubClass()
{
std::cout << "it's Sub Deconstruct!" << std::endl;
}
};
int main()
{
BaseClass *p_b = new BaseClass;
delete p_b;
std::cout << "---------------------------------\n";
SubClass *p_s = new SubClass;
delete p_s;
std::cout << "---------------------------------\n";
BaseClass *p_b_s = new SubClass;
delete p_b_s;
std::cin.get();
}
成功释放,这就是为何要在基类加上virtual
防止内存泄露,保证安全释放。