【问题标题】:Destructor ordering in inheritance hierarchy继承层次结构中的析构函数排序
【发布时间】:2013-02-28 20:45:11
【问题描述】:

如果我有以下层次结构:

  • F 类包含类型的成员对象(E 类和 D 类,按此顺序声明)
  • F 类继承具体类 C 类
  • C 类继承抽象/纯虚类 B 类
  • 类 B 继承具体类类 A

如果调用 F 类对象的析构函数,则按以下顺序发生以下情况:

  1. F 类(派生最多的)析构函数被调用并完成
  2. D 类(成员对象 2)析构函数被调用并完成
  3. E 类(成员对象 1)析构函数被调用并完成
  4. C 类(F 的基础)析构函数被调用并完成
  5. A 类(B 的基础,C 的基础)析构函数被调用并完成
  6. B 类(虚拟,C 基础)析构函数被调用并完成

这是正确的吗?所以基本上到最后C继承了虚拟B,虚拟B继承了A,但是C被销毁,然后是A,然后是虚拟B?

编辑:C++ 常见问题解答说:

“虚拟基类是特殊的——它们的析构函数在 最派生类的构造函数的结尾"

这是我想要理解的?

【问题讨论】:

  • 描述有点混乱:它不是虚拟的,而是继承。所以你的 C 类实际上继承了 B 类,或者你可以说 B 是 C 的 虚基。当然,B 是抽象的,它包含纯虚函数,但顺序无关紧要构造函数/析构函数。
  • @anatolyg 那么您将如何重新措辞 C++FAQ,因为我完全被它所说的弄糊涂了?

标签: c++ inheritance polymorphism virtual-destructor


【解决方案1】:

析构函数的执行顺序与构造函数相反。这就是您需要知道的几乎所有内容。

更新:它甚至适用于虚拟基地。您只需要意识到虚基是在任何其他基类之前构造的。

【讨论】:

  • 是的,但我读到虚拟类的析构函数在最后被调用,无论它们在层次结构中的位置如何?
  • C++ 常见问题解答,第 272 页说“虚拟基类是特殊的——它们的析构函数在最派生类的构造函数的末尾调用”。所以在我的例子中,这是否意味着在 F 类之后?
  • @user997112:你真的应该添加代码,而不是描述层次结构是什么......你真的在使用virtual继承吗?从描述中看不清楚。请用真实代码更新问题。
  • @DavidRodríguez-dribeas 我没有代码,我想了解 C++ FAQ 引用的含义。
  • @user997112:不清楚你对抽象/纯虚拟类的意思,我认为你理解你写的,只需使用基本的C++来布局代码.. .
【解决方案2】:

也许将析构函数调用的顺序表示为一种算法是最简单的。

销毁

  1. 做程序员在析构函数体内写的任何东西:F::~F() { do_this; do_that; }
  2. 销毁(调用析构函数)成员
  3. 销毁(调用析构函数)非虚拟基类
  4. 销毁(调用析构函数)虚拟基类

此算法由语言(或编译器)执行,因此程序员只能控制第一步。

注意:每个进一步的步骤都是递归的。

析构函数调用的顺序与构造函数调用的顺序相反(很高兴知道,因为构造顺序很直观)。虚拟基地的破坏顺序指定为

基类图的深度优先从左到右遍历

幸运的是,您不需要这个,因为您只有一个。

【讨论】:

  • 好的,所以在我的示例中,我在超类 A 和类 C 之间的继承层次结构中有一个虚拟基类(B 类)。这是否意味着 B 的析构函数将在两个析构函数之后被调用A类和C类?
  • 否(只需编写一个测试程序并在调试器中跟踪它)
猜你喜欢
  • 2011-10-28
  • 1970-01-01
  • 2013-10-24
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 2020-10-24
相关资源
最近更新 更多