#include <iostream>
class A
{
public:
A() { std::cout << " A ctor" << std::endl; }
A(int i) { std::cout << " A ctor i" << std::endl; }
~A() { std::cout << " A dtor" << std::endl; }
};
class B: public A
{
public:
B() : A () { std::cout << " B ctor" << std::endl; }
~B() { std::cout << " B dtor" << std::endl; }
};
class C: public A
{
public:
B _b;
C() : _b (), A () { std::cout << " C ctor" << std::endl; }
~C() { std::cout << " C dtor" << std::endl; }
};
int main ()
{
C c;
}
输出结果为:
A ctor
A ctor
B ctor
C ctor
C dtor
B dtor
A dtor
A dtor
init的顺序是什么。清单?为什么,在init中。在C的ctor之前调用的C,C的列表?我认为输出应该是:
A ctor
B ctor
A ctor
C ctor
C dtor
A dtor
B dtor
A dtor
感谢。
答案 0 :(得分:4)
在初始化列表中编写初始化的顺序并不重要,初始化顺序由其他规则独立于该列表确定:
C
时首先调用基类构造函数A
。属于基类的所有内容都是在此步骤中构建的(基类和属于基类的成员变量),就像构建该基类的普通对象一样。答案 1 :(得分:2)
在派生类构造函数之前调用基类构造函数。这允许派生类在构造期间使用基类中的成员。
在毁灭期间,情况正好相反。子类破坏发生在基类之前,原因完全相同。
如果你考虑一下 - 这是完全合理的。基类不知道子类,但反之则不然。这决定了顺序,以便一切按预期工作。
答案 2 :(得分:0)
我认为你的困惑是为什么C的初始化列表从右到左处理而不是左写。这是因为,编译器以“后进先出”的方式处理参数。因此顺序:第一个A的c'tor。由于_b是从A派生的B的对象,因此在派生类之前构造基类,因此调用A c'tor,然后调用B的c'tor。最后,C的c'tor被称为。当C的对象被破坏时,它遵循相反的顺序。
答案 3 :(得分:0)
如果您使用GNU编译器,-Wall
选项将为您提供帮助。