(Note): List of constructor initialization and constructor Initialization
1. To better describe the initialization list, an error code is first introduced:
1 # include <iostream> 2 3 # include "string. h "4 using namespace std; 5 6 class Student 7 {8 private: 9 int Num, Chinese, Maths, English; 10 float Total; 11 char Name [20]; 12 public: 13 Student () {}// default constructor 14 Student (char name [20], int num, int chinese, int maths, int english); 15 16}; 17 Student:: Student (char name [20], int num, int chinese, int maths, int english) {18 int n; 19 for (n = 0; n <strlen (name ); n ++) 20 Name [n] = name [n]; 21 Num = num; 22 Chinese = chinese; 23 English = english; 24 Maths = maths; 25 Total = maths + chinese + english; 26} 27 28 int main () 29 {30 int I, j; 31 int num, chinese, maths, english; 32 char name [20]; 33 Student std [5]; // because of the default constructor, you can use 34 35 for (I = 0; I <5; I ++) 36 {37 cin> name [20]> num> chinese> maths> english; 38 std [I] (name [20], num, chinese, maths, english); 39 for (j = 0; j <20; j ++) 40 name [j] = '\ 0'; 41 42} 43}
View Code
The above code prompts an error during compilation:
[Error] no match for call to '(Student) (char &, int &)'
Locate the following row of std [I] (name [20], num, chinese, maths, english). The cause of this code error is that the Student array is incorrectly defined, call the constructor to assign values. In fact, the constructor is in Student std [5]; the default constructor is called to initialize the definition. (If you do not understand the execution process of the constructor, refer to my previous notes ). All Constructors (which can be default constructor or non-trivial constructor) are called at the time of definition. calls after definition are not called initialization, but assigned values. The person who wrote this error code obviously did not understand how the constructor was executed,
The objective is to call the constructor cyclically for initialization. Of course, we can write the correct code according to his idea, and change the above error line to std [I]. student (name [20], num, chinese, maths, english );
This looks like the object itself calls the constructor for initialization. Unfortunately, compilation is not possible, and the following error message is displayed:
[Error] invalid use of 'student: Student'
This error occurs because C ++ requires that the system automatically call the constructor During the definition, and the object cannot call the constructor.
Solution:
1. You can initialize the SDK directly when defining the SDK. To facilitate Problem description, we changed the Student std [5] above to an array element in the Code and removed the for loop,
It becomes the following code (this code is only supported by c ++ 11 ):
1 # include <iostream> 2 3 # include "string. h "4 using namespace std; 5 6 class Student 7 {8 private: 9 int Num, Chinese, Maths, English; 10 float Total; 11 char Name [20]; 12 public: 13 Student () {}// default constructor 14 Student (char name [20], int num, int chinese, int maths, int english); 15 16}; 17 Student:: Student (char name [20], int num, int chinese, int maths, int english) {18 int n; 19 for (n = 0; n <strlen (name ); n ++) 20 Name [n] = name [n]; 21 Num = num; 22 Chinese = chinese; 23 English = english; 24 Maths = maths; 25 Total = maths + chinese + english; 26} 27 28 int main () 29 {30 int I, j; 31 int num, chinese, maths, english; 32 char name [20]; 33 Student std [1] ={{ name, num, chinese, maths, english }}; 34 35 36}
View Code
2. You can also define a series of pointers and call new to construct class objects each time you construct them.
For example:
1 Student *std[5];2 for(i=0;i<5;i++)3 {4 cin>>name[20]>>num>>chinese>>maths>>english;5 std[i]=new Student(name,num,chinese,maths,english);6 */
To better understand how the constructor executes the new object, simply change the above Code as follows:
1 # include <iostream> 2 3 # include "string. h "4 using namespace std; 5 6 class Student 7 {8 private: 9 int Num, Chinese, Maths, English; 10 float Total; 11 public: 12 Student () {} // default constructor 13 Student (int num); 14 15}; 16 Student: Student (int num) {17 18 cout <"no." <num <"constructor" <endl; 19 Num = num; 20 cout <"Num =" <num <endl; 21} 22 23 int main () 24 {25 int I; 26 int num, chinese, maths, english; 27 28 Student * std [5]; 29 for (I = 0; I <5; I ++) 30 {31 std [I] = new Student (I ); // automatically call the constructor 32} 33} every time a piece of memory is applied}
View Code
Result:
Through the above error example, we found that the cause of some code errors is that we did not understand the execution process of the constructor. I wonder if you have found out
In the above code, I always assign values to the member variables of the Student class within the constructor. Strictly speaking, this is not initialization (for initialization concepts, refer to the previous notes ),
This is a process of value Assignment calculation. when defining a variable, the value assignment code in the constructor is automatically executed.
2. the initialization list is displayed.
The code below: There is a symbol behind the constructor, followed by the initialization of the member variable.
1 class Student 2 {3 private: 4 int m_num, m_maths; 5 public: 6 Student () {}// default constructor 7 Student (int num, int maths ): m_num (num), m_maths (maths) 8 {9 10 cout <"entering the computing stage" <endl; 11 cout <"m_num =" <num <endl; 12} 13 14 };
To better understand the initialization list, we first need to know that the execution of the constructor can be divided into two phases: the initialization phase and the computing phase. The initialization phase is prior to the computing phase. The initialization stage corresponds to the initialization list, and the computing stage is the function body part of the constructor. The initialization stage is executed before the computing stage, as shown in the following program:
1 # include <iostream> 2 3 # include "string. h "4 using namespace std; 5 6 class Student 7 {8 private: 9 int m_num, m_maths; 10 public: 11 Student () {} // default constructor 12 Student (int num, int maths); 13}; 14 Student: Student (int num, int maths): m_num (num ), m_maths (maths) 15 {16 cout <"before entering the computing stage m_num =" <m_num <endl; 17 this-> m_num = 2; 18 cout <"Check m_um =" <m_num <endl; 19} 20 21 int main () 22 {23 24 Student A (1, 2); 25} after entering the computing stage}
The test results are shown as follows:
We can see that before entering the computing stage, we can see that the value of m_num is changed to 1, and the value of m_num is changed to 2 after the computing stage. Therefore, the initialization stage is completed before the computing stage.
The following describes the advantages of the initialization list: it is more efficient than assigning values in the constructor (function body) (only for class variables ). The following two sections of code and corresponding result images are provided. Code 2 changes the Construction Function of Student2 to the initialization list form based on Code 1.
Code 1:
1 # include <iostream> 2 3 using namespace std; 4 5 class Student1 {6 public: 7 int a; 8 9 Student1 () // No parameter constructor 10 {11 cout <"default constructor Student1" <endl; 12} 13 14 Student1 (const Student1 & t1) // copy the constructor 15 {16 cout <"copy constructor Student1" <endl; 17 this-> a = t1.a; 18} 19 20 Student1 & operator = (const Student1 & t1) // value assignment operator 21 {22 cout <"value assignment function Student1" <endl; 23 this-> a = t1.a; 24 return * this; 25} 26}; 27 class Student228 {29 public: 30 31 Student1 test; 32 Student2 (Student1 & t1) {// Figure 1 result 33 test = t1; 34} 35}; 36 int main () 37 {38 39 Student1 A; 40 Student2 B (A); 41 42}
View Code
Code 2:
1 # include <iostream> 2 3 using namespace std; 4 5 class Student1 {6 public: 7 int a; 8 9 Student1 () // No parameter constructor 10 {11 cout <"default constructor Student1" <endl; 12} 13 14 Student1 (const Student1 & t1) // copy the constructor 15 {16 cout <"copy constructor Student1" <endl; 17 this-> a = t1.a; 18} 19 20 Student1 & operator = (const Student1 & t1) // value assignment operator 21 {22 cout <"value assignment function Student1" <endl; 23 this-> a = t1.a; 24 return * this; 25} 26}; 27 class Student228 {29 public: 30 31 Student1 test; 32 Student2 (Student1 & t1 ): test (t1) {}33}; 34 int main () 35 {36 37 Student1 A; 38 Student2 B (A); 39 40}
View Code
Code 1 diagram:
Code 2 diagram:
It can be seen that the calculation result of the first code calls two constructor and one value assignment function, while Code 2 calls one constructor and one copy function.
When the amount of code is large, you will find that code 2 is more efficient than Code 1.