非静态数据成员上的成员初始值设定项列表和默认成员初始值设定项有什么区别? [英] What's the differences between member initializer list and default member initializer on non-static data member?

查看:192
本文介绍了非静态数据成员上的成员初始值设定项列表和默认成员初始值设定项有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to understand what's the differences of using one form rather than the other (if any).

代码1 (直接在变量上初始化):

Code 1 (init directly on variables):

#include <iostream>

using namespace std;

class Test 
{
public:
    Test() {
        cout<< count;
    }

    ~Test();

private:
    int count=10;
};

int main()
{
    Test* test = new Test();
}

代码2 (使用构造函数上的初始化列表初始化):

Code 2 (init with initialization list on constructor):

#include <iostream>

using namespace std;

class Test 
{
public:
    Test() : count(10) {
        cout<< count;
    }

    ~Test();

private:
    int count;
};

int main()
{
    Test* test = new Test();
}

语义上是否存在差异,还是仅仅是语法上的?

Is there any difference in the semantics, or it is just syntactic?

推荐答案

成员初始化



在两种情况下,我们都在谈论成员初始化
请记住,成员是在在类中声明的顺序

在第二个版本中:

Test() : count(10) {

:count(10)是构造函数初始值设定项( ctor初始化器)和 count(10)成员初始化器,是成员初始化器的一部分清单。我喜欢将其视为初始化发生的真实或主要方式,但它不能确定初始化的顺序。

: count(10) is a constructor initializer (ctor-initializer) and count(10) is a member initializer as part of the member initializer list. I like to think of this as the 'real' or primary way that the initialization happens, but it does not determine the sequence of initialization.

在第一个版本中:

private:
    int count=10;

count 具有默认成员激励器。它是后备选项。如果构造函数中不存在任何成员,它将用作成员初始值设定项,但是在该类中,确定了初始化成员的顺序。

count has a default member intitializer. It is the fallback option. It will be used as a member initializer if none is present in the constructor, but in the class the sequence of members for initialization is determined.

12.6.2节初始化基准和成员中,标准的第10条


如果给定的非-static数据成员同时具有
括号或相等初始化程序和mem初始化程序,执行由mem-initializer指定的初始化
,而非静态数据
成员的大括号或等于初始化器将被忽略。 [示例:给定

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) { }
// ...
};

A(int)构造函数将简单地将i初始化为arg,
和我的brace-or-equalinitializer中的副作用不会占
的位置。 —结束示例]

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中的聚合,但这已经已针对C ++ 14更新

Something else to keep in mind would be that if you introduce a non-static data member initializer then a struct will no longer be considered an aggregate in C++11, but this has been updated for C++14.


使用一种形式而不是另一种形式(如果有
的话)有什么区别。

what's the differences of using one form rather than the other (if any).




  • 区别在于两个选项的优先级。直接指定的构造函数初始值设定项具有优先级。在这两种情况下,我们最终都会通过不同的路径得到成员初始化器。

  • 最好使用默认的成员初始化程序,因为


    • 然后编译器可以使用该信息生成构造函数的

    • 您可以在一处并按顺序查看所有默认值。

    • 它可以减少重复。然后,您只能将异常放入手动指定的成员初始化程序列表中。

      • The difference is the priority given to the two options. A constructor initializer, directly specified, has precedence. In both cases we end up with a member initializer via different paths.
      • It is best to use the default member initializer because
        • then the compiler can use that information to generate the constructor's initializer list for you and it might be able to optimize.
        • You can see all the defaults in one place and in sequence.
        • It reduces duplication. You could then only put the exceptions in the manually specified member initializer list.
        • 这篇关于非静态数据成员上的成员初始值设定项列表和默认成员初始值设定项有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆