【问题标题】:Is there any harm in overriding an "empty" virtual destructor with another one?用另一个覆盖“空”虚拟析构函数有什么害处吗?
【发布时间】:2016-03-28 21:54:33
【问题描述】:

假设我从一个带有“空”虚拟析构函数的类继承:

// base.h
class Base {
 public:
  // ...
  virtual ~Base();
};

// base.cc
Base::~Base() {}

如果我不需要在派生类的析构函数中做任何显式工作,那么添加另一个像 bleow 这样的“空”有什么害处吗?

// derived.h
class Derived : public Base {
 public:
  // ...
  ~Derived() override;
};

// derived.cc
Derived::~Derived() {}

this question 的回答说不是必要,但是有什么害处吗?

【问题讨论】:

  • 除了线外定义的成本,没有,没有什么坏处。
  • 把总有一天不得不维护你的代码的程序员当作一个知道你住在哪里的杀人狂。而且不会有任何伤害。
  • 如果我们忽略你的~Derived造成的编译错误,不会有什么坏处。但话又说回来 - ~Base 也没有编译,所以至少它没有变得更糟。
  • 也许担心的是 ~Base() 不会被调用,除非 ~Derived() 显式调用它(即类似于其他虚拟方法覆盖的工作方式)。如果是这样,请不要担心——无论如何都会调用所有析构函数,因此子类析构函数不可能“隐藏”基类析构函数,例如导致资源泄漏。
  • @KerrekSB 有趣的是,内联定义的成本更高。

标签: c++ inheritance destructor virtual-inheritance virtual-destructor


【解决方案1】:

添加另一个像 bleow 这样的“空”有什么害处吗?

每个内联Derived 的构造函数的翻译单元都必须生成内联析构函数的外联副本,以将其地址放入Derived 的虚拟表中。链接器会丢弃重复的虚拟表,但是,析构函数的离线副本及其调试信息会保留下来。

使析构函数脱机可防止上述代码重复并使您的目标文件、可执行文件和共享库更小。

【讨论】:

  • @MatthieuM.: 过去 20 年中几乎所有的链接器也可以内联外联函数。
  • @MooingDuck:没错,但具有误导性。 (1) 链接时间优化是可选的,一些大型库需要大量资源; (2) 链接时间优化只解决包含定义的库的问题,而不是它的任何客户端, 动态链接时。
猜你喜欢
  • 2017-04-21
  • 2011-02-04
  • 2021-03-27
  • 2018-03-08
  • 2016-02-05
  • 2012-07-30
  • 2020-03-06
  • 2012-01-31
  • 1970-01-01
相关资源
最近更新 更多