施工人员订购

时间:2010-10-02 17:55:24

标签: c++

#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

感谢。

4 个答案:

答案 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选项将为您提供帮助。