有虚函数的基类应具有虚析构函数
5.1.4 ID_missingVirtualDestructor
为了避免意料之外的资源泄漏,有虚函数的基类都应该具有虚析构函数。
通过基类指针析构派生类对象时,如果基类没有虚析构函数会导致标准未定义的行为,无法正确执行派生类的析构函数。
示例:
class A {
public:
A() = default;
~A() = default; // Non-compliant, missing ‘virtual’
virtual int foo() = 0;
};
class B: public A {
int *m, n; // New resource
public:
B(int s): m(new int[s]), n(s) {}
~B() { delete[] m; }
int foo() override { return n; }
};
A* p = new B(10);
....
delete p; // Undefined behavior, may leak
由于基类 A 的析构函数不是虚函数,delete p 只调用了基类析构函数,派生类对象的资源没有得到释放。
例外:
class C {
....
protected:
~C(); // Compliant
};
如果有意阻止外界通过基类指针析构对象,如析构函数是 protected,可不受本规则限制。
依据
ISO/IEC 14882:2003 5.3.5(3)-undefined
ISO/IEC 14882:2003 12.4(7)
ISO/IEC 14882:2011 5.3.5(3)-undefined
ISO/IEC 14882:2011 12.4(9)