我发现The rule of Zero(第32页)中提到的Peter Sommerlads Slides非常引人注目。
虽然,我似乎记得有一个严格的规则,一个有来定义析构函数虚拟,如果该类有< strong>虚拟成员,实际上是派生的。
struct Base {
virtual void drawYourself();
virtual ~Base() {}
};
struct Derived : public Base {
virtual void drawYourself();
};
析构函数的主体甚至可能是空的(它只需要vtbl中的条目)。
我似乎记得使用层次结构时
int main() {
Base *obj = new Derived{};
obj->drawYourself(); // virtual call to Derived::drawYourself()
delete obj; // Derived::~Derived() _must_ be called
}
然后delete obj
调用正确的析构函数非常重要。这是否正确,如果我完全忽略析构函数定义它将不成为虚拟,因此会调用错误的数字?
struct Base {
virtual void drawYourself();
// no virtual destructor!
};
这引出了我的最后一个问题:
编辑:在答案中提醒我,我的问题的1sr版本有错误的假设。相关(虚拟)析构函数位于Base
,而不是Derived
。但我的问题是:我是否需要声明(虚拟)析构函数?
答案 0 :(得分:6)
它实际上是必须声明为虚拟的基础析构函数,并且它在派生类中自动虚拟化:
struct Base {
virtual void drawYourself();
virtual ~Base() = default;
};
struct Derived : public Base {
virtual void drawYourself();
};
但除此之外,零的规则仍然存在。
如果按照这样做的方式执行,或者如果省略virtual
析构函数,则只需通过基指针delete
派生对象时获得未定义的行为。