C ++ - 成员初始化和增量的顺序

时间:2015-12-23 16:15:18

标签: c++ class constructor

我正在寻找一些测试来提高我的C ++知识。以下是其中一个练习:以下程序的输出是什么?

#include <iostream>

class A
{
public:
    A(int n = 0) : m_i(n)
    {
        std::cout << m_i;
        ++m_i;
    }

protected:
    int m_i;
};

class B : public A
{
public:
    B(int n = 5) : m_a(new A[2]), m_x(++m_i) { std::cout << m_i; }

    ~B() { delete [] m_a; }

private:
    A m_x;
    A *m_a;
};

int main()
{
    B b;
    std::cout << std::endl;
    return 0;
}

好吧,我尝试了这段代码,答案是02002。我来这里有一些解释,因为我不明白为什么02002是结果。 我会解释我的推理,但有些人可以告诉我,我错在哪里吗?

让我们将“str”称为要打印的当前字符串。构建b对象时:

  1. 调用A的构造函数。 str =&gt; 0m_i =&gt; 1
  2. m_a(new A[2])的构建。 str =&gt; 000
  3. m_x(++m_i)的构建。 str =&gt; 0002m_i =&gt; 3
  4. str的最后更新(在B的构造函数中)=&gt; str =&gt; 00023
  5. 以下是我的问题:

    • 为什么m_i 2的最终价值而不是3
    • 为什么在m_x(++m_i)之前完成m_a(new A[2])的构建?我试图交换m_x和m_a初始化的位置,答案仍然是相同的:02002

2 个答案:

答案 0 :(得分:12)

  

为什么最终值为m_i 2而不是3

因为new A[2]创建了两个与*this无关的单独实例。 m_i实例的b仅在A::AB::B(两次)中递增。

如果m_i的增量应该在同一个实例上执行(例如m_i是一个引用),那么认为{{1}的最终值会更合理应该是m_i(数组中有两个对象 - 另外两个增量)。

  

为什么在4之前完成m_x(++m_i)的构建?

因为the order of initialization depends on the order of declaration of the data members,而不是在成员初始化列表中编写初始化的顺序。

答案 1 :(得分:4)

构建b时,首先构建A的{​​{1}}部分。这会在输出中显示B。然后我们得到0因为2首先发生,因为m_x(++m_i)在类中首先列出。由于正在构建m_x的{​​{1}}部分m_i为1,AB,现在我们有++m_i。然后运行2,它给我们2 02(每个数组的一个)。这使我们处于m_a(new A[2])。然后,我们从0获得最终0200,因为2仍然是{ std::cout << m_i; }的{​​{1}}。