Question 2:
I changed the question and used the Class X mentioned in the previous article. The Code is as follows:
1 class X
2 {
3 public:
4 X () {cout <"default construct" <endl ;}
5 X (int a): I (a) {cout <"construct" <I <endl ;}
6 ~ X () {cout <"desconstruct" <I <endl ;}
7 X (const X & x): I (x. I)
8 {
9 cout <"copy construct" <I <endl;
10}
11 X & operator ++ ()
12 {
13 cout <"operator ++ (pre)" <I <endl;
14 ++ I;
15 return * this;
16}
17 const X operator ++ (int)
18 {
19 cout <"operator ++ (post)" <I <endl;
20 X x (* this );
21 ++ I;
22 return x;
23}
24 X & operator = (int m)
25 {
26 cout <"operator = (int)" <endl;
27 I = m;
28 return * this;
29}
30 X & operator = (const X & x)
31 {
32 cout <"operator = (X)" <endl;
33 I = x. I;
34 return * this;
35}
36 /////////////////////////
37 friend ostream & operator <(ostream & OS, const X & x)
38 {
39 OS <x. I;
40 return OS;
41}
42 friend X operator + (const X & a, const X & B)
43 {
44 cout <"operator +" <endl;
45 return X (a. I + B. I );
46}
47 //////////////////////////
48 public:
49 int I;
50 };
What is the output of the following code?
1 X a (10), B (20 );
2 X c = a + B;
Let's take a look at the actual running results after GCC4.5 (default compilation option) AND MSVC9.0 (both debug and release) are compiled:
Construct 10
Construct 20
Operator +
Construct 30
Desconstruct 30
Desconstruct 20
Desconstruct 10
The output is as follows:
Construct 10
Construct 20 // corresponds to X a (10), B (20 );
Operator + // call the "+" operator
Construct 30 // call X (int) {...}, 44 rows
Desconstruct 30 // analysis structure of variable c
Desconstruct 20 // Analysis of variable B
Desconstruct 10 // Analysis of variable
The result shows that "operator =" is not output during the entire execution process, which means that the "=" operator is not called at all, and the whole process is more concise and efficient than I think, with no temporary objects, no copy structure.
Why is the result? This is mainly due to the ability of the compiler to optimize return values.
I will not elaborate on the optimization of returned values, but it should be noted that MSVC9.0 only enables NRVO in RELEASE mode by default, that is, optimization of the returned values of the specified object, and an important detail in return value optimization is embodied in this example: Why is "opeartor =" not displayed in the entire output, that is, why is the "=" operator not called.
Now let's change the code to the following:
X a (10), B (20), c;
C = a + B; // here we separate the structure and value assignment of c.
The execution result is as follows:
Construct 10 // construct
Construct 20 // construct B
Default construct // construct c
Operator + // call the "+" operator
Construct 30 // call X (int) {...}, 44 rows
Operator = (X) // call the "=" operator
Desconstruct 30 // The structure of the temporary object created in line 45 of the Code
Desconstruct 30 // analysis structure of variable c
Desconstruct 20 // Analysis of variable B
Desconstruct 10 // analysis structure of variable c
Compare the output results before and after, you can find three more lines
Default construct
Operator = (X)
Desconstruct 30
The reason for this difference is that the default constructor is called for initialization when c is defined. Therefore, after the first statement is executed, c is an existing object, therefore, the second statement does not have the right to directly modify the content of c. You must call the value assignment operator "=" to generate a temporary object. In the first example, because c is not created before the second statement is executed, the compiler can directly construct the return value of expression a + B in the memory of c, so as to optimize the temporary object and the call to "=.