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

C++ - order of member initialization and incrementation

本文关键字:顺序 成员 初始化 C++      更新时间:2023-10-16

我正在寻找一些测试来提高我的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对象时:

    str
  1. => 0m_i => 1A
  2. 建造m_a(new A[2]) . str => 000
  3. 构造m_x(++m_i) . str => 0002m_i => 3
  4. str 的上次更新(在 B 的构造函数中(=> str => 00023

以下是我的问题:

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

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

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

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

为什么m_x(++m_i)的建设是在m_a(new A[2])之前完成的?

因为初始化的顺序取决于数据成员的声明顺序,而不是在成员初始值设定项列表中编写初始化的顺序。

当你构造b时,首先构造BA部分。 这会在输出中给出0。 然后我们得到2,因为m_x(++m_i)首先发生,因为m_x在类中列在第一位。 由于m_i是正在建造的B A部分的 1,因此++m_i给出了2,现在我们有02. 然后运行m_a(new A[2])它给我们 2 个0(数组的每个成员一个(。 这使我们处于0200。 然后我们从{ std::cout << m_i; }那里得到最后的2,因为m_i仍然2 m_x(++m_i) .