c++ - 非静态数据成员的成员初始值设定项列表和默认成员初始值设定项之间有什么区别?

标签 c++ class variables initialization ctor-initializer

我想了解使用一种形式与使用另一种形式(如果有)的区别是什么。

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/

相关文章:

Java:从方法调用返回两个整数

git - 如何在PowerShell中更改变量的Unicode

c - 在循环范围外使用局部变量

c++ - 流转换过滤器 : invalid PKCS #7 block padding found using AES decryption

design-patterns - 类(class)互动设计模式

python - 在 Python 中使用类作为命名空间是个好主意吗

java - 文件/变量错误 Java

c++ - 与模板类的链接错误

c++ - 指数的前 n 位

c++ - 我应该对最简单的类型使用 boost::optional 来表示 nullable int double 等吗?