重写析构函数是好的做法吗?

Is it good practice to override the destructor?

本文关键字:析构函数 重写      更新时间:2023-10-16

override析构函数是好的做法吗?为什么或为什么不呢? 例:

class Foo : Base
{
public:
~Foo() override {}
};
struct Base {
virtual ~Base() {}
};
struct Foo : Base {
~Foo() override {}
};

这将编译。

struct Base {
~Base() {}
};
struct Foo : Base {
~Foo() override {}
};

这不。

struct Base {
~Base() {}
};
struct Foo : Base {
virtual ~Foo() {}
};

这将编译。

活生生的例子。

如果您的目标是在Foo中声明您希望Base具有virtual析构函数,最简单的方法是在~Foo上使用override关键字。 由于通过Base*删除Foo*的语义会根据~Foo是否virtual而发生显着变化,这可能对某些人有用。

其他人可能会因为使用术语override来指代这种情况而感到冒犯。

确定人们因使用override而受到冒犯是否比能够在Foo中声明Base具有虚拟析构函数更重要或更不重要,因此通过指向Base的指针删除Foo实例是定义的行为。 我不能为你做这个决定。

正如@HowardHinnant在注释中所述,添加显式析构函数会产生后果;如果这样做,请遵循 5 法则并=default=delete或实现复制/移动对象构造/赋值运算符。

static_assertBase具有虚拟析构函数可能更容易,除非您出于其他原因需要析构函数。