多重继承的情况下的破坏顺序

时间:2015-07-20 14:03:23

标签: c++ language-lawyer multiple-inheritance

在多重继承的情况下,是否明确定义了破坏的顺序?

struct A
{
   ~A(){std::cout << "A\n";}   
};

struct B
{
   ~B(){std::cout << "B\n";}   
};

struct AB : public B, public A
{
    ~AB(){std::cout<<"AB\n";}   
};

int main()
{
    AB ab;
}

对于给定的代码,我的编译器打印:

AB
B
A

但我使用更复杂的结构(包括CWinApp),我得到不同的结果。订单定义明确吗?如果是这样,订购规则是什么?

3 个答案:

答案 0 :(得分:17)

来自[class.dtor]:

  基础和   成员按照构造函数完成的相反顺序销毁(见12.6.2)。

构造函数的排序,来自[class.base.init]:

  

在非委托构造函数中,初始化按以下顺序进行:
   - 首先,只有最派生类(1.8)的构造函数,虚拟基类才被初始化[...]
   - 然后,直接基类按声明顺序初始化,因为它们出现在 base-specifier-list 中   (无论 mem-initializers 的顺序如何)。

对于你的例子:

struct AB : public B, public A

构造顺序为B,然后是A,然后是AB。因此,销毁订单为AB,然后是A,然后是B

答案 1 :(得分:6)

C ++ 11标准明确了这个(S10.1),用于多重继承

  

除非由指定,否则推导的顺序并不重要   构造函数初始化的语义(12.6.2),清理(12.4),   和存储布局(9.2,11.1)。

但是你可以保证销毁订单与构造相反。

答案 2 :(得分:1)

来自friendly manual(缩写#2):

  
      
  1. 调用类的析构函数。
  2.   
  3. 违反声明的非静态成员的破坏者。
  4.   
  5. 以与声明相反的顺序调用非虚基类的析构函数。
  6.   
  7. 虚拟基类的析构函数按声明的相反顺序调用。
  8.   

因此,您的编译器会发出以AB,B,A。

的顺序破坏的代码

[编辑20150725:Barry的重复评论最终让我注意到我已经打错了#34;这不是&#34; as&#34;这也是&#34;。当然,输入它之后,在我之前我无法看到它。咩。因此,下面改变了一个词。]

来自isocpp.org&#39; s FAQ的订单。该条目引用了关于构造函数排序的相同问题,其中文本&#34;注意,顺序B1然后B2(或B1a然后B1b)由基类出现在类的声明中的顺序确定,而不是按照初始化程序出现在派生类的初始化列表中的顺序。&#34;出现,突出显示声明顺序是相关的顺序。