Reference Address http://www.cnblogs.com/bigshow/archive/2008/11/10/1330514.html
often see such a declaration:t& func (t& t), what is the difference between such a declaration and T-func (T-t)? The explanation in the book is to improve efficiency, how to improve efficiency? What has been done internally? This article provides a thorough troubleshooting of reference parameters and reference returns with 8 small examples.
First look at the reference parameter and the reference return value in the member function of the class:
class definitionClass A
{
Public
int x;
A () {}//constructor
A (const a& Other)//copy constructor
{
This->x = other.x;
cout << "Copy" << Endl;
}
~a () {}//destructor
a& operator= (const a& Other)//assignment function
{
This->x = other.x;
cout << "Assign" << Endl;
return *this;
}
void Func1 (A A)
{
}
void Func2 (a& A)
{
}
A func3 ()
{
return *this;
}
a& Func4 ()
{
return *this;
}
};
This class is simple, has only one member variable x, and defines the default constructor, copy constructor, destructor, and assignment The value function. To be able to see more clearly which copy constructor and assignment function is being called, add Some output information to the two functions.
The class also defines four member functions, each of which analyzes the execution of these four functions.
(1) Call Func1 () in the main () function:
call FUNC1 ()int main ()
{
A A1, A2;
A2.FUNC1 (A1);
return 0;
}
func1 () output Copy
Why is there such an output? This is because the value parameter is passed in Func1 (), so a temporary object is generated before the function body is executed, and then the copy constructor of the class is called to initialize the temporary object, thereby outputting "copy". the temporary object is manipulated inside the function, and any modifications made to the temporary object are not reflected on the function's arguments.
(2) in the main () function, call Func2 () to compare with Func1 ():
call FUNC2 ()int main ()
{
A A1, A2;
A2.FUNC2 (A1);
return 0;
}
func2 () output results
The result is nothing output.
This is because a reference parameter is passed in, so there is no need to produce a temporary object inside the function to hold the object information, so the copy constructor is not called. This is the role of reference parameters, reduce the copy of the object once, improve the function efficiency .
(3) Call FUNC3 () in the main () function:
call FUNC3 ()int main ()
{
A A1, A2;
A2 = A1.func3 ();
return 0;
}
func3 () output results
Copy
Assign
Why does it output "Copy"? This is because the function takes a value return, so in order to save the return value, you need to create a temporary object and then call the copy constructor of the class to copy the contents of the *this to the temporary object, and then return the temporary object . Finally, the contents of the temporary object are assigned to the new object through the assignment function.
(4) in the main () function, call Func4 () to compare with Func3 ():
call FUNC4 ()int main ()
{
A A1, A2;
A2 = A1.func4 ();
return 0;
}
func4 () output results
Assign
only the assignment function is called, which is a reference function that takes a reference return, and therefore directly returns the reference *this of the object itself, not you need to create a temporary object to hold the object information, so the copy constructor is not called. Finally , the content of the image itself is assigned to the new object directly through the assignment function. This is the function of the reference return value, which reduces the copy of the object once and improves the efficiency of the function.
To summarize: in member functions of a class, the use of reference parameters and reference return values does not need to produce a temporary object, reducing the copy of the object once and improving the efficiency of the function.
So what happens if you return a parameter as a return value and receive a return value with a reference? The following defines four global functions:
global function a& func5 (a& A)
{
return A;
}
a& Func6 (A A)
{
return A;
}
A Func7 (a& a)
{
return A;
}
A Func8 (a a)
{
return A;
}
(5) Call Func5 () in the main () function:
call FUNC5 ()int main ()
{
A A1;
a1.x = 1;
a& A2 = Func5 (A1);
a1.x++;
cout << a1.x << Endl;
cout << a2.x << Endl;
return 0;
}
Func5 () output results
2
2
Func5 () takes a reference parameter and returns the parameter as a reference to the return value, so A2 is a reference to A1, any changes to the A1 are reflected on the A2, so the value of the member variable x for A1 and A2 is the same.
(6) Call Func6 () in the main () function:
call Func6 ()int main ()
{
A A1;
a1.x = 1;
a& A2 = Func6 (A1);
a1.x++;
cout << a1.x << Endl;
cout << a2.x << Endl;
return 0;
}
When compiling, a warning is reported:
Warning
Warning C4172:returning address of local variable or temporary
Func6 () output results
Copy
2
4198610
The warning means that a reference to a local variable is returned, which is actually wrong. A local variable is released before the function returns , so it is actually A2 referenced to an unknown piece of memory, which can be seen from the output's a2.x value "4198610" . As for the output "Copy", because the use of the value parameters, which have been discussed above, here no longer repeat.
(7) Call Func7 () in the main () function:
Call Func7 ()int main ()
{
A A1;
a1.x = 1;
const a& A2 = FUNC7 (A1);
a1.x++;
cout << a1.x << Endl;
cout << a2.x << Endl;
return 0;
}
FUNC7 () Output results
Copy
2
1
This is a very special usage, since Func7 () takes a value return, so before the function returns it will produce a temporary object and executes the copy constructor once. This is equivalent to A2 referencing a temporary object. As I said earlier, the temporary pair will be released before the function returns, but why is the output here normal? This is a special case where C + + stipulates that if there is a reference to a temporary object, the lifetime of the temporary object will be extended to the same reference as this one. This will explain the above output: A2 refers to a temporary object instead of referencing A1, so any change to A1 does not affect A2.
Note: In the VC compilation environment, const a& a2 = FUNC7 (A1); This line of statements can be preceded by no "const", but no "const" in g++ or other versions of the compiler will produce a compilation error. Plus "Const" is more compliant with the C + + standard because the temporary object is not visible and is not allowed to change the contents of the temporary object through the reference.
(8) Call Func8 () in the main () function:
call FUNC8 ()int main ()
{
A A1;
a1.x = 1;
const a& A2 = FUNC8 (A1);
a1.x++;
cout << a1.x << Endl;
cout << a2.x << Endl;
return 0;
} Func8 () output results
Copy
Copy
2
1
through the above analysis, this output is also very well understood: because the use of the value of the parameters, so in the function body execution the copy constructor is called once, and the value return value is used, so the copy constructor is called once before the function returns. number, which is the origin of the first two "Copy". In addition, a2 refers to a temporary object instead of referencing A1, so any changes to A1 do not affect A2.
To summarize:
If you use a reference to receive a reference return value, the returned reference must have a longer lifetime and cannot refer to a local variable.
If you use a reference to receive a value that returns a value, a temporary object is referenced, and the lifetime of the object is extended to match the reference .
Copy construction of reference parameter and reference return value class