C++ - 成员初始化和递增的顺序
C++ - order of member initialization and incrementation
我正在寻找一些测试来提高我的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
- =>
0
,m_i
=>1
A
- 建造
m_a(new A[2])
. str =>000
- 构造
m_x(++m_i)
. str =>0002
,m_i
=>3
- 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::A
和 B::B
(两次(中递增。
如果m_i
的递增应该在同一实例上执行(例如,m_i
作为引用(,那么认为m_i
的最终值应该4
会更合理(数组中有两个对象 - 两个额外的增量(。
为什么
m_x(++m_i)
的建设是在m_a(new A[2])
之前完成的?
因为初始化的顺序取决于数据成员的声明顺序,而不是在成员初始值设定项列表中编写初始化的顺序。
当你构造b
时,首先构造B
的A
部分。 这会在输出中给出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)
.
相关文章:
- 在循环中按顺序遍历成员变量
- C++成员的析构函数顺序与shared_ptr
- 按类成员的顺序对包含类对象的C++向量进行排序
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 用作成员构造函数参数的函数的求值顺序
- 成员初始值设定项的顺序
- 内联初始化的静态 const 类成员的初始化顺序保证
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 共享库中静态功能成员的破坏顺序
- C++11 成员类初始化顺序
- 静态内联成员初始化顺序
- 更改 std::set 作为成员属性的顺序
- 位成员顺序相反?
- C++中的类私有成员的内存顺序是否得到保证?
- 静态成员的静态阵列:初始化顺序惨败的可能性
- C++-销毁顺序-函数的静态成员在主类析构函数之前被销毁
- 为什么在定义静态成员变量时不遵循定义顺序
- 如何维护类成员的顺序,并且仍然有一个可工作的构造函数
- 编译时随机化结构成员的顺序
- 类模板中成员变量的顺序