【发布时间】:2017-04-21 08:29:02
【问题描述】:
每个人都知道基类的析构函数通常必须是虚拟的。但是派生类的析构函数是什么呢?在 C++11 中,我们有关键字“override”和显式使用默认析构函数的能力。
struct Parent
{
std::string a;
virtual ~Parent()
{
}
};
struct Child: public Parent
{
std::string b;
~Child() override = default;
};
在 Child 类的析构函数中同时使用关键字“override”和“=default”是否正确?在这种情况下编译器会生成正确的虚拟析构函数吗?
如果是,那我们是否认为这是一种很好的编码风格,我们应该总是这样声明派生类的析构函数以确保基类析构函数是虚拟的?
【问题讨论】:
-
也可以
static_assert(std::has_virtual_destructor<Parent>::value, "contract violated"); -
请注意,基类析构函数不一定是虚拟的。所以这只是(可能)一个好主意,如果这是一个要求。
-
如果它有效,我喜欢它,但milleniumbug 更好(更清晰的意图)。另一方面,Stroustrup 讨厌防止常见错误的“编码标准”结构,并坚持编译器应该生成适当的警告。
-
我认为@milleniumbug 的方法清楚地表达了意图。如果我在代码库中遇到
~Child() override = default;,我可能会删除该行。 -
“花点时间学习一些 C++ 可能是值得的”——请参阅this post 末尾的“责备程序员”。另外,请注意,我实际上并没有说我不理解
static_assert,只是它比override版本更令人困惑。这是真的,因为它更长、更冗长,并且使用了标准库的一个相对晦涩的特性。