【问题标题】:C++ - order of member initialization and incrementationC++ - 成员初始化和递增的顺序
【发布时间】:2015-12-23 16:15:17
【问题描述】:

我正在寻找一些测试来提高我的 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 => 0, m_i => 1
  2. m_a(new A[2]) 的构造。 str => 000
  3. m_x(++m_i) 的构造。 str => 0002, m_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_xB 类中被声明为之前 m_aB(int n = 5) : m_a(new A[2]), m_x(++m_i) 格式错误,应该是B(int n = 5) : m_x(++m_i), m_a(new A[2])
  • @YSC 是正确的,至少,使用 gcc 编译时会收到大量警告(我不确定其他人)
  • @YSC B(int n = 5) : m_a(new A[2]), m_x(++m_i) 不是格式错误的。也许它应该是不合格式的,但不幸的是它不是。
  • 你是对的,我收到警告:“test.cpp:27: warning: ‘B::m_a’ will be initialized after”

标签: c++ class constructor


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 感谢您的回答!我刚刚明白为什么是 2 而不是 3。我还在 m_x 的构造过程中添加了一个增量。
  • @Ptiseb 如果您以与声明成员不同的顺序初始化成员,一些编译器(MingW 和 VC)会发出警告。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多