为什么析构函数建议声明为virtual?
为什么C++建议将基类的析构函数声明为virtual?如果不这样做,通过基类指针删除派生类对象时会发生什么?哪些类的析构函数不需要virtual?
回答
Yahuda
核心原因:当通过基类指针删除派生类对象时,如果析构函数不是virtual,只会调用基类析构函数,派生类的析构函数不会被执行,导致派生类部分资源泄漏。
Base* p = new Derived();
delete p; // 若~Base()非virtual: 只调用~Base(), ~Derived()不执行
后果:派生类中动态分配的内存、文件句柄、锁等资源无法释放,造成资源泄漏。这是未定义行为(UB)。
标准规定[ISO C++ 5.3.5/3]:通过基类指针delete派生类对象时,若基类析构非virtual,行为未定义。
何时不需要virtual:
- 类不打算作为基类(标记final)
- 类不通过基类指针多态删除(如栈对象、unique_ptr)
- POD类型或traits类
设计原则:如果类中有任意虚函数,析构函数应声明为virtual。如果类设计为基类接口,应提供virtual析构函数。C++11的default可简化:virtual ~Base() = default;。