虚析构函数是一个在基类中使用关键字virtual声明的析构函数。这保证了在通过基类指针删除对象时,派生类的析构函数会被调用。
class Base { public: virtual ~Base() { /* ... */ } }; class Derived : public Base { public: ~Derived() override { /* ... */ } }; Base* ptr = new Derived(); delete ptr; // 将调用两个析构函数
如果没有虚析构函数,行为可能不正确——派生类的析构函数不会被调用,这将导致资源泄漏!
如果你的基类没有任何虚函数,是否需要将析构函数声明为虚的?
答案:是的,如果类预计会被继承并通过指向基类型的指针进行删除。 即使没有其他虚函数,析构函数的虚拟性也是正确删除后代所必需的。
class Shape { public: virtual ~Shape() {} };
故事1
在一个大型图形库项目中,通过基类指针删除绘图对象时,OpenGL资源(缓冲区、纹理)泄漏——相应的释放位于派生类的析构函数中,而它们没有被调用。
故事2
在网络库中,对于TCP协议删除会话时,未调用通过公共基接口管理的派生类的析构函数。这导致了大量套接字挂起和描述符限制耗尽。
故事3
在C++嵌入式系统中,错误声明(非virtual)的基类析构函数导致输入输出控制器的系统资源的内存泄漏,设备在多个驱动程序更新循环后故障。