虚拟析构函数的默认覆盖

新手上路,请多包涵

大家都知道基类的析构函数通常必须是虚的。但是派生类的析构函数是什么呢?在 C++11 中,我们有关键字“覆盖”和显式使用默认析构函数的能力。

 struct Parent
{
  std::string a;
  virtual ~Parent()
  {
  }

};

struct Child: public Parent
{
  std::string b;
  ~Child() override = default;
};

在 Child 类的析构函数中同时使用关键字“override”和“=default”是否正确?在这种情况下,编译器会生成正确的虚拟析构函数吗?

如果是,那么我们是否可以认为这是一种很好的编码风格,并且我们应该始终以这种方式声明派生类的析构函数以确保基类析构函数是虚拟的?

原文由 Sandro 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 793
1 个回答

根据 CppCoreGuidelines C.128 ,派生类的析构函数不应声明为 virtualoverride

如果基类析构函数声明为虚拟,则应避免声明派生类析构函数 virtualoverride 。一些代码库和工具可能会坚持对析构函数进行覆盖,但这不是这些指南的建议。

更新:回答为什么我们对析构函数有特殊情况的问题。

方法覆盖 是一种语言功能,它允许子类或子类提供其超类或父类之一已经提供的方法的特定实现。子类中的实现通过提供与父类中的方法具有相同名称、相同参数或签名以及相同返回类型的方法来覆盖(替换)超类中的实现。

换句话说,当您调用重写的方法时,只有该方法的最后一个实现(在类层次结构中)实际执行,而必须调用 所有 析构函数(从最后一个子级到根父级)才能正确释放所拥有的所有资源由对象。

因此,我们并没有真正替换(覆盖)析构函数,而是在对象析构函数链中添加了额外的一个。

更新:此 CppCoreGuidelines C.128 规则已更改(由 14481446 问题)以简化已经详尽的例外列表。所以一般规则可以概括为:

对于类用户,包括析构函数在内的所有虚函数都是同样多态的。

在国有子类上标记析构函数 override 是教科书式的卫生,你们都应该按常规进行( 参考)。

原文由 Alexandre A. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题