Members of the initialization team (member Initia
There are four situations where you must use member initialization list:
1. When initializing a reference member;
2. When initializing a const member;
3. When a base class constructor is called, and it has a set of parameters;
4. When a member class constructor is called, and it has a set of parameters;
In these four cases, the program can be compiled and run correctly, but the efficiency is not high. For example:
1 class Word {2 String name; 3 int _cnt; 4 Public : 5 Word () {6 0; 7 0 ; 8 }
Here, Word constructor produces a temporary string object, initializes it, assigns a temporary object to _name with a assignment operator, and then destroys the temporary object.
The following are the possible internal expansion results of Constuctor:
Word::word (/*This pointer goes here*/){ //call the default constructor of string_name. String::string (); //Create a temporary objectString temp = string (0); //"memberwise" copy _name_name. String::operator=(temp); //Destroying temporary objectsTemp. string::~String (); _cnt=0;}
The code is reviewed and revised repeatedly, resulting in a significantly more efficient implementation:
Word::word: _name (0) { 0;}
It will expand into this way:
1 Word::word (/*Thispointer goes here*/)2{3 // call string (int) constructor4 _name. String::string (0); 5 0 ; 6 }
For each member of the member initialization list, the compiler will insert code within constructor according to member in the order declared in the class, before any explicit user code.
The appearance of confusion between the initialization order and the order of items in the initialization list can lead to unexpected risks:
class X { int i; int public: X (int val): J (Val), I (j) {}}
The code looks like the initial value of J is Val, and I set the initial value to J. The problem is that I (j) in the initialization list is actually executed earlier than J (Val) because of the order of the declarations. However, because J does not initially have an initial value, the execution result of I (j) causes I to not predict its values. So it's always advisable to put one member initialization operation with the other and put it inside the constructor, like this:
X::X (int val): J (Val) { = j;}
Here's another interesting question. Initialization the items in the list are placed in constructor, will they continue to be declared in order? That is, known:
X::X (int val): J (Val) { = j;}
Is the code above correct? The answer is: yes. Because the initialization list item is placed before explicit user code.
Briefly, the compiler will process the initialization list one by one and possibly reorder it to reflect the order in which members are declared. It will place some code into the constructor body and precede any explicti code.
"C + +" Deep Exploration C + + object Model reading notes--constructor semantics (the semantics of Constructors) (iv)