Author: gzshun. Original Works. Reprinted, please indicate the source!
Source: http://blog.csdn.net/gzshun
In terms of concept, constructor can be considered to be implemented in two phases:
1. Initialization phase;
2. Common computing stage. (The computing stage consists of all the statements in the constructor)
Whether or not the Members display initialization in the constructor initialization list, data members of the class type are always initialized in the initialization phase. Initialization occurs before the start of the computing phase.
Suggestion: Use the constructor to initialize the list.
Note: you must use the initialization method for any const or reference type member and any member of the class type without the default constructor.
You can use constructors to initialize the list to avoid compilation errors.
Explanation: no default constructor class? What does that mean?
In most compilers, a class is declared. If the class has no explicit declaration and constructor definition, the compiler will generate a default constructor in the compilation phase. If you declare a constructor in this class, the compiler will not generate default constructor, but will use your own constructor. To avoid compilation errors, it is best to use the constructor initialization list to initialize objects of this class.
----- Excerpt from C ++ primer Chinese Version 4th
Class member initialization includes the initialization of Class Object members and class data members. The key to Initialization is the initialization list of the constructor. In the initialization list of the constructor, the order is also required. Only constructors can have the effect of member initialization. Common member functions do not have this function, for example:
[CPP]
View plaincopy
- Void cinit: setxy (int x, int y): MX (x), My (y)
- {
- }
This Initialization is incorrect. setxy is not a constructor. Therefore, common member functions can only set the values of variables or objects by assigning values.
[CPP]
View plaincopy
- Void cinit: setxy (int x, int y)
- {
- MX = X;
- My = y;
- }
A cinit class is declared as follows:
[CPP]
View plaincopy
- Class cinit
- {
- Public:
- Cinit (int x, int y );
- Void show () const;
- PRIVATE:
- Int MX;
- Int my;
- };
- Void cinit: Show () const
- {
- Cout <"MX =" <MX <Endl
- <"My =" <my <Endl;
- }
I. Basic usage of the constructor initialization list
This is the usage of the normal initialization list
Initialization:
[CPP]
View plaincopy
- Cinit: cinit (int x, int y): MX (x), My (y)
- {
- }
The result is equivalent
Assignment:
[CPP]
View plaincopy
- Cinit: cinit (int x, int y)
- {
- MX = X;
- My = y;
- }
Ii. Sequence of member Initialization
In the constructor initialization list, the initialization order of members is the order of declared members.
Example 1: James wants to initialize MX with X and then initialize my
[CPP]
View plaincopy
- Cinit: cinit (int x, int y): MX (x), My (MX)
- {
- }
- Cinit test (2, 3 );
- Test. Show ();
The result is:
[Plain]
View plaincopy
- MX = 2
- My = 2
Both Mx and my are initialized successfully.
Example 2: Li Si wants to initialize my first and then use my to initialize MX
[CPP]
View plaincopy
- Cinit: cinit (int x, int y): My (Y), MX (my)
- {
- }
- Cinit test (2, 3 );
- Test. Show ();
The result is:
[Plain]
View plaincopy
- MX = 2147344384 (different machines may be inconsistent)
- My = 3
Obviously, MX is not initialized, and my is initialized to 3.
It can be seen from this that the constructor executes initialization actions in the declared order of variables. Therefore, in example 2, the constructor first initializes MX, but at this time my is not initialized, this is the case. In the initialization list of the constructor,It is best to initialize the class according to the declared sequence of the member variables in the class.
Iii. Under what circumstances will the constructor be used to initialize the list?
1. Const object
2. Reference Type object
Because the const object and the reference type object can only be initialized and cannot be assigned a value, they must be initialized in the initialization list.
3. Class Object (described below)
To illustrate 3. Class Object (described below), if a parent class is defined as follows:
[CPP]
View plaincopy
- Class ca {
- Public:
- CA () {cout <"using CA's constractor/N ";}
- CA (int K) {cout <"using CA's 2nd constractor, K is" <k <Endl; M = K ;};
- Virtual ~ CA () {cout <"using CA's disconstractor/N ";}
- Void output () {cout <"The M is" <m <Endl ;}
- PRIVATE:
- Int m;
- };
Note that Class A has a private member M.
Assume that a subclass is defined as follows:
[CPP]
View plaincopy
- Class CB: public CA {
- Public:
- CB (int K) {M = K ;}
- };
Obviously, it is wrong. Class B cannot directly access Class A member M.
This definition is also incorrect:
[C-sharp]
View plaincopy
- Class CB: public CA {
- Public:
- CB (int K) {_ super: Ca (INT) k );}
- };
In this way, a temporary variable instance of the CA class is constructed in CB (int K), and the function is no longer executed. If:
[C-sharp]
View plaincopy
- Cb B (2 );
The execution result is:
Using Ca's constractor
Using Ca's 2nd constractor, K is 2
Using Ca's disconstractor
Using Ca's disconstractor
This indicates that a CB instance is constructed by default by calling Ca (), and then a Ca (2) instance is declared.
The correct method is as follows:
[C-sharp]
View plaincopy
- Class CB: public CA {
- Public:
- CB (int K): Ca (k ){}
- };
This shows the constructor that calls the parent class in the subclass.
4. In constructor, Which of the following is more efficient for value assignment initialization and initialization list initialization? Why?
Let's look at an example and we can see that:
[CPP]
View plaincopy
- # Include <iostream>
- Using namespace STD;
- Class cobj
- {
- Public:
- Cobj ()
- {
- Cout <"Call default constructor" <Endl;
- }
- Cobj (const cobj & OBJ)
- {
- MX = obj. mx;
- Cout <"Call replication constructor" <Endl;
- }
- Cobj & operator = (const cobj & OBJ)
- {
- If (& OBJ! = This)
- {
- MX = obj. mx;
- }
- Cout <"Data assignment" <Endl;
- Return * this;
- }
- PRIVATE:
- Int MX;
- };
- Class cinit
- {
- Public:
- Cinit (const cobj & OBJ): mobj (OBJ)
- {
- // Mobj = OBJ;
- }
- PRIVATE:
- Cobj mobj;
- };
- Int main ()
- {
- Cobj OBJ;
- Cout <Endl;
- Cinit test (OBJ );
- Return 0;
- }
1. If the cinit constructor is:
[CPP]
View plaincopy
- Cinit (const cobj & OBJ): mobj (OBJ)
- {
- }
The execution result is:[Plain]
View plaincopy
- The output of the constructor that calls the default constructor // cobj OBJ;
- Call the replication Constructor
When the initialization list of the constructor cinit initializes the mobj object, the copy constructor is called once, and a total of 1 behavior is required.
2. If the cinit constructor is:
[CPP]
View plaincopy
- Cinit (const cobj & OBJ)
- {
- Mobj = OBJ;
- }
The execution result is:
[Plain]
View plaincopy
- The output of the constructor that calls the default constructor // cobj OBJ;
- Call the default constructor
- Data assignment
When assigning values to the mobj object in the constructor body, the default constructor is called first, and the operator = value assignment operator is called. A total of two actions are required.
So we can come to the following conclusion:For user-defined class types, it is more efficient to use the constructor initialization list for initialization than to assign values to initialization in the constructor body. For built-in types, the efficiency is similar.
5. Example of using the constructor initialization list
[CPP]
View plaincopy
- /* Class member initialization: Find a rectangle composed of two points */
- # Include <iostream>
- Using namespace STD;
- Class ccenterpoint
- {
- Public:
- Ccenterpoint (INT posx, int posy): mposx (posx), mposy (posy)
- {
- }
- Void showpos () const
- {
- Cout <"midpoint coordinates between two points: (" <mposx <"," <mposy <")" <Endl;
- }
- PRIVATE:
- Int mposx;
- Int mposy;
- };
- Class carea
- {
- Public:
- Carea (INT length, int width): mlength (length), mwidth (width)
- {
- }
- Void showarea () const
- {
- Cout <"rectangular area composed of 2 points:" <mlength * mwidth <Endl;
- }
- PRIVATE:
- Int mlength;
- Int mwidth;
- };
- Class crect
- {
- Public:
- Crect (INT posx1, int posy1, int posx2, int posy2)
- : Mpoint (posx1 + posy1)/2, (posx2 + posy2)/2 ),
- Marea (posX2-posX1, posY2-posY1)
- {
- }
- Void show () const
- {
- Mpoint. showpos ();
- Marea. showarea ();
- }
- PRIVATE:
- Ccenterpoint mpoint;
- Carea Marea;
- };
- Int main ()
- {
- Crect rect (10,100, 20,200 );
- Rect. Show ();
- Return 0;
- }
Execution result:
[Plain]
View plaincopy
- Midpoint coordinates between two points: (55,110)
- Rectangular area composed of 2 points: 1000
Happy learning!