我正在寻找一些测试来提高我的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
对象时:
A
的构造函数。 str =&gt; 0
,m_i
=&gt; 1
m_a(new A[2])
的构建。 str =&gt; 000
m_x(++m_i)
的构建。 str =&gt; 0002
,m_i
=&gt; 3
B
的构造函数中)=&gt; str =&gt; 00023
以下是我的问题:
m_i
2
的最终价值而不是3
?m_x(++m_i)
之前完成m_a(new A[2])
的构建?我试图交换m_x和m_a初始化的位置,答案仍然是相同的:02002
。答案 0 :(得分:12)
为什么最终值为
m_i
2
而不是3
?
因为new A[2]
创建了两个与*this
无关的单独实例。 m_i
实例的b
仅在A::A
和B::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,A
会B
,现在我们有++m_i
。然后运行2
,它给我们2 02
(每个数组的一个)。这使我们处于m_a(new A[2])
。然后,我们从0
获得最终0200
,因为2
仍然是{ std::cout << m_i; }
的{{1}}。