C++ initializes list learning

  • 2020-04-02 01:24:07
  • OfStack

What is an initialization list
Unlike other functions, constructors can have an initialization list in addition to a name, a list of arguments, and the body of the function, which starts with a colon followed by a series of comma-separated initialization fields. In C++, the only difference between structs and classes is that the default is different in terms of gram accessibility, and we don't care about accessibility here, so the following code is illustrated with structs.


struct foo
{
    string name ;
    int id ;
    foo(string s, int i):name(s), id(i){} ; //Initialization list
};

The two execution phases of the constructor
Constructor execution can be divided into two phases, the initialization phase and the computation phase, with the initialization phase preceding the computation phase.

Initialization phase
All class type members are initialized during the initialization phase, even if the member does not appear in the constructor's initialization list.

Calculate phase
Typically used to perform assignments inside a constructor, the following code defines two structures, where Test1 has a constructor, a copy of the constructor, and an assignment operator, to facilitate viewing the results. Test2 is a test class that takes an object from Test1 as a member. Let's see how the constructor for Test2 executes.


struct Test1
{
    Test1() //Parameter free constructor
    { 
        cout << "Construct Test1" << endl ;
    }
    Test1(const Test1& t1) //Copy constructor
    {
        cout << "Copy constructor for Test1" << endl ;
        this->a = t1.a ;
    }
    Test1& operator = (const Test1& t1) //Assignment operator
    {
        cout << "assignment for Test1" << endl ;
        this->a = t1.a ;
        return *this;
    }
    int a ;
};
struct Test2
{
    Test1 test1 ;
    Test2(Test1 &t1)
    {
        test1 = t1 ;
    }
};

The calling code

Test1 t1 ;
Test2 t2(t1) ;

The output

The < img style = "border = 0 border - BOTTOM: 0 px; BORDER - LEFT: 0 px; BORDER - TOP: 0 px; BORDER - RIGHT: 0 px "Alt =" "SRC =" / / files.jb51.net/file_images/article/201309/201309090929443.png ">

To explain, the first line of output corresponds to the first line in the calling code to construct a Test1 object. The second line of output corresponds to the code in the Test2 constructor, which initializes the object test1 with the default constructor, known as the initialization phase. The third line prints out the assignment operator for Test1, performing the assignment on Test1, in what is known as the computation phase.

Why use the initialization list
There are two ways to initialize a member of a class, either by using an initialization list or by performing an assignment in the constructor body. The use of initialized lists is mainly based on performance issues. For built-in types such as int, float, etc., there is not much difference between initializing a class table and initializing in the constructor body, but for class types, it is better to use initialized lists. Why? As you can see from the above test, there is one less call to the default constructor with the initialization list, which is very efficient for data-intensive classes. As in the example above, we use the initialization list to implement the constructor for Test2


struct Test2
{
    Test1 test1 ;
    Test2(Test1 &t1):test1(t1){}
}

Using the same calling code, the output is as follows.

The < img style = "border = 0 border - BOTTOM: 0 px; BORDER - LEFT: 0 px; BORDER - TOP: 0 px; BORDER - RIGHT: 0 px "Alt =" "SRC =" / / files.jb51.net/file_images/article/201309/201309090929444.png ">

The first line of output corresponds to the first line of the calling code. The second line prints out the list of initializations for Test2 and calls the copy constructor directly to initialize test1, eliminating the need to call the default constructor. So a good rule of thumb is to use an initialization list whenever you can.

What must be in the initialization list
In addition to performance issues, there are times when an initialization list is necessary, and there are times when an initialization list must be used

Constant member. Because constants can only be initialized and cannot be assigned, they must be placed in the initialization list
Reference types. References must be initialized at the time of definition and cannot be re-assigned, so they are also in the initialization list
There is no class type for the default constructor, because you can use the initialization list to initialize without calling the default constructor, and instead call the copy constructor initialization directly.
Let's look at an example of a class that doesn't have a default constructor.


struct Test1
{
    Test1(int a):i(a){}
    int i ;
};
struct Test2
{
    Test1 test1 ;
    Test2(Test1 &t1)
    {
        test1 = t1 ;
    }
};

This code won't compile because the line test1 = t1 in Test2's constructor is actually executed in two steps.

1. Call Test1's default constructor to initialize Test1
2. Call the assignment operator of Test1 to assign a value to Test1

But because Test1 does not have a default constructor, the so-called first step cannot be executed, so the compilation error occurs. The correct code is as follows, using an initialization list instead of an assignment.
The same code at the page code block index 3
The initialization order of the member variables
Members are initialized in the order they appear in the class, not in the order they appear in the initialization list, depending on the code.


struct foo
{
    int i ;
    int j ;
    foo(int x):i(x), j(i){}; //Ok, initialize I first, then j
};

Now look at the following code

struct foo
{
    int i ;
    int j ;
    foo(int x):j(x), i(j){} //The I value is undefined
};

The value of I here is undefined because although j comes before I in the initialization list, I is defined before j, so I is initialized first, but I is initialized by j, so j is not initialized yet, so the value of I is undefined. So, a good practice is to initialize in the order that the members are defined.


Related articles: