Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
338 views
in Technique[技术] by (71.8m points)

c++ - What's the differences between member initializer list and default member initializer on non-static data member?

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

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();
}

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Member initialization

In both cases we are talking about member initialization. Keep in mind that the members are initialized in the sequence in which they are declared in the class.

Code 2: Member initializer list

In the second version:

Test() : 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.

Code 1: Default member initializer

In the first version:

private:
    int count=10;

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.

From section 12.6.2 Initializing bases and members, item 10 of the standard:

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 ]

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.


Differences

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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...