关于父类使用虚析构函数
当你写一个需要扩展的类或者子类,或者说只要你允许一个类可以被继承,那么应该将该类的析构函数声明为虚析构函数,否则该父类无法被安全地扩展。
如果不使用虚析构函数,当子类的对象指针传参给一个函数,而这个函数的参数是父类指针类型,那么通过多态父类指针引用子类对象,如果在函数内部删除了父类的指针,子类对象的析构函数就无法调用了。
#include <iostream>
class Base
{
public:
Base() { std::cout << "Base 构造\n"; }
//~Base() { std::cout << "Base 析构\n"; }
virtual ~Base() { std::cout << "Base 析构\n"; } // 虚析构函数
};
class Derived : public Base
{
public:
Derived() { m_Array = new int[10]; std::cout << "Derived 构造\n"; } // 申请堆内存
~Derived() { delete[] m_Array; std::cout << "Derived 析构\n"; } // 释放堆内存
private:
int* m_Array;
};
void main()
{
Base* base = new Base();
delete base;
// Base 构造
// Base 析构
std::cout << std::endl;
Derived* derived = new Derived();
delete derived;
//Base 构造
//Derived 构造
//Derived 析构
//Base 析构
std::cout << std::endl;
Base* poly = new Derived(); // 通过父类引用子类对象
delete poly;
// 1. 当Base中不是虚析构函数时,没有调用Derived的析构函数,内存泄漏
/*
Base 构造
Derived 构造
Base 析构
*/
// 2. 当Base中是虚析构函数时,自动调用Derived的析构函数,释放内存
/*
Base 构造
Derived 构造
Derived 析构
Base 析构
*/
std::cin.get();
}