在多重继承的情况下,是否明确定义了破坏的顺序?
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
),我得到不同的结果。订单定义明确吗?如果是这样,订购规则是什么?
答案 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):
- 调用类的析构函数。
- 违反声明的非静态成员的破坏者。
- 以与声明相反的顺序调用非虚基类的析构函数。
- 虚拟基类的析构函数按声明的相反顺序调用。
醇>
因此,您的编译器会发出以AB,B,A。
的顺序破坏的代码[编辑20150725:Barry的重复评论最终让我注意到我已经打错了#34;这不是&#34; as&#34;这也是&#34;。当然,输入它之后,在我做之前我无法看到它。咩。因此,下面改变了一个词。]
来自isocpp.org&#39; s FAQ的订单。该条目引用了关于构造函数排序的相同问题,其中文本&#34;注意,顺序B1然后B2(或B1a然后B1b)由基类出现在类的声明中的顺序确定,而不是按照初始化程序出现在派生类的初始化列表中的顺序。&#34;出现,突出显示声明顺序是相关的顺序。