我想了解使用一种形式与使用另一种形式(如果有)的区别是什么。
Code 1 (直接在变量上初始化):
#include <iostream>
using namespace std;
class Test
{
public:
Test() {
cout<< count;
}
~Test();
private:
int count=10;
};
int main()
{
Test* test = new Test();
}
Code 2 (在构造函数上使用初始化列表进行初始化):
#include <iostream>
using namespace std;
class Test
{
public:
Test() : count(10) {
cout<< count;
}
~Test();
private:
int count;
};
int main()
{
Test* test = new Test();
}
语义上有什么区别,还是只是句法上的区别?
最佳答案
成员初始化
在这两种情况下,我们都在谈论 member initialization . 请记住,成员是在 sequence in which they are declared 中初始化的。在类里。
代码2:成员初始化列表
在第二个版本中:
Test() : count(10) {
:count(10)
是一个构造函数初始值设定项 ( ctor-initializer ) 而 count(10)
是一个成员初始值设定项 作为一部分成员初始值设定项列表。我喜欢将其视为初始化发生的“真实”或主要方式,但它并不能确定初始化的顺序。
代码1:默认成员初始化
在第一个版本中:
private:
int count=10;
count
有一个默认成员初始化器。这是后备选项。如果构造函数中没有成员初始化器,它将用作成员初始化器,但在类中确定初始化成员的顺序。
来自12.6.2 初始化基和成员部分,标准的第 10 项:
If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-initializer is ignored. [ Example: Given
struct A { int i = / some integer expression with side effects / ; A(int arg) : i(arg) { } // ... };
the A(int) constructor will simply initialize i to the value of arg, and the side effects in i’s brace-or-equalinitializer will not take place. —end example ]
还有一点要记住,如果引入非静态数据成员初始值设定项,则结构将不再被视为 C++11 中的聚合,但这一直是 updated for C++14 .
差异
what's the differences of using one form rather than the other (if any).
- 区别在于两个选项的优先级。直接指定的构造函数初始值设定项具有优先权。在这两种情况下,我们最终都会通过不同的路径得到一个成员初始值设定项。
- 最好使用默认的成员初始化器,因为
- 然后编译器可以使用该信息为您生成构造函数的初始化列表,并且它可能能够进行优化。
- 您可以在一处按顺序查看所有默认值。
- 它减少了重复。然后,您只能将异常放在手动指定的成员初始值设定项列表中。
关于c++ - 非静态数据成员的成员初始值设定项列表和默认成员初始值设定项之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36600187/