1
Abstract: after C++11, initialization at declaration -> initialization list -> constructor initialization.

This article is shared from HUAWEI CLOUD COMMUNITY "How to write efficient, elegant, and credible code series ways to initialize class members 160e2adf999a42", the original author: I am a big watermelon.

First of all, you must first understand which types of member initialization methods C++ supports, and which one do you commonly use.

  • Initialization method 1: Initialization list
class A
{
public:
    int a; // 初始化列表
    A(int a_):a(a_){}
};
  • Initialization method two: constructor initialization
class A
{
public:
    int a; // 初始化列表
    A(int a_, bool b) { a = a_; }
};
  • Initialization method 3: Initialization during declaration (also called in-place initialization, supported after c++11)
class A
{
public:
    int a = 1; // 声明时初始化
    A() {}
};

In C++98, the method of using the equal sign "=" plus the initial value in the class declaration is supported to initialize the static member constants in the class. This way of declaration is also called "in-place" declaration. In-place declaration is very convenient when writing code, but C++98 has very high requirements for in-place declaration in classes. If the static member does not satisfy the constant property, it cannot be declared in place, and even the static member of the constant can only be an integral type or an enumeration type to be initialized in place. The initialization of non-static member variables must be carried out in the constructor. For example, the following code is compiled in c++98

class Init
{
public:
    Init(): a(0) []
    Init(int d): a(d) {}
private:
    int a;
    const static int b = 0;

    int c = 1;           // member, cannot pass build
    static int d = 0;    // member, cannot pass build

    static const double e = 1.3;      // not int or enum type, cannot pass build
    stati const char* const f = "e";  // not int or enum type, cannot pass build
}

This is very inconvenient, so in C++11, the standard allows many forms of initialization of non-static member variables. Specifically, in addition to the initialization list, in C++11, the standard also allows the use of equal signs = or curly braces {} to initialize non-static member variables in place.

struct init {
    int a = 1;
    double b {1.2};
};

As you know, there are several situations where it is recommended to use list initialization first

  • const member variables can only be initialized with the member initialization list, and cannot be assigned
  • initialize data members are subject
  • need to initialize reference member data

The specific reasons are not detailed here, you can go to "C++ Primer".

The essence of constructor initialization is assignment operation ("="). There are two problems with this method. One is that compared with the initialization list and in-place initialization, this method is less efficient; the second is that there may be errors.

Let me talk about the first one. Temporary objects will be generated during the assignment process. The construction and destruction of temporary objects will cause efficiency loss. The method of initializing the list avoids the problems caused by temporary object shrinkage.

The second is that if you do not rewrite or prohibit the assignment constructor, C++ will quietly add the default assignment constructor, which may also cause problems at this time.

Since C++11, these three initialization methods can be used, and there will be no conflicts, but there is a priority order between them. This priority comes from the time sequence of their initialization, and the initialization is later. Will overwrite the previous ones, the initialization order of member variables is

Initialization at declaration -> Initialization list -> Constructor initialization

Therefore, if the three initialization methods exist at the same time, then the last retained member variable value must be the initialized value in the constructor.

#include <iostream>
using namespace std;
class A 
{
public:
    int a = 1;
    A(int a_) :a(2) { a = 3; }
};

int main()
{
    A a;
    cout << "a.a=" << a.a << endl;
    return 0;
}

// a.a=3

Since there are so many initialization methods, when should one apply?

1. Use scenarios for initialization at the time of declaration

  • One advantage is that it is intuitive. You give an initial value when you declare, bravo. When others are looking at your code, you can click on the declaration and you can see the initial value you assign, without having to look at the constructor. What value
  • The second advantage is more useful. For example, you have to define multiple constructors, and each constructor is initialized with a list initialization method. How troublesome it is. Please see the example below. Mom no longer has to worry about it. I want to use others. Initialization method
class Group {
public:
    Group() {}
    Group(int a): data(a) {}
    Group(Mem m): mem(m) {}
    Group(int a, Mem m, string n): data(a), mem(m), name(n) {}
private:
    int data = 1;
    Mem mem{0};
    string name{"Group"};
};

2. Use scenarios for list initialization

I have mentioned three scenes before, so I will repeat them here.

  • const member variables can only be initialized with the member initialization list, and cannot be assigned in the constructor
  • The initialized data member is an object
  • Need to initialize reference member data

However, you need to pay attention to the order in which the list is initialized, but the IDE will prompt you

3. Use scenarios for constructor initialization

  • The first one is in the copy and assignment constructor (otherwise how to call the assignment constructor)
  • The second one is the more boring situation. For example, if you want to initialize several member functions to a value, please see the following example
class Group {
public:
    Group() {data1 = data2 = data3 = 0;}
private:
    int data1;
    int data2;
    int data3;
};

In a word, in-place initialization and list initialization are preferred.

Click to follow, and get to know the fresh technology of


华为云开发者联盟
1.4k 声望1.8k 粉丝

生于云,长于云,让开发者成为决定性力量