Item 21:don ' t try to return a reference if you must return a object
As mentioned in Item 20, it is better to pass a reference than to pass a value in most cases. It's good to pursue this, but never return an empty reference or pointer. A typical scenario is as follows:
class Rational{ int N, D; Public: raitonal(int Numerator=0, int Denominator=1);};//return value for what is const please refer to item 3friend Const Rational operator*(Const Rational& LHS, Const Rational& RHS);Rational a, b;Rational C = a*b;
Attentionoperator*Returned is theRationalInstancea*bis called when theoperator*(), the return value is copied and used to initialize thec。 The process involves multiple constructs and destructors:
- before the function call ends, the return value is copied, the copy constructor is called
-
c is initialized, call copy constructor
c is initialized, the copy of the return value is refactored
Can we avoid these function calls by passing references? This requires that the object be created in the function to be returned to the caller, whereas the function has only two ways to create the object: Create it in the stack, or create it in the heap. creating in the stack is obviously wrong:
Const Rational& operator*(Const Rational& LHS, Const Rational& RHS){ Rational result(LHS.N*RHS.N, LHS.D*RHS.D); return result;}
Customers get theresultis always empty. Because the reference is just a name, when the function call endsresultis destroyed. It returns aex-resultThe reference. So what is the result of creating in the heap?
Const Rational& operator*(Const Rational& LHS, Const Rational& RHS){ Rational *result = New Rational(LHS.N*RHS.N, LHS.D*RHS.D); return *result;}
The problem came again, since it is new object, then who comes delete ? For example, the following customer code:
rational w x , span class= "n" style= "" >y z w = x * y * z
above such reasonable code will lead to memory leaks, then operator* is clearly not reasonable. At this point you may want to store the return value with a static variable, or you can avoid the return value being constructed again. But static variables are first faced with a thread-safety problem, and there is a problem when the customer needs more than one return value to exist:
if (( a * b ) == ( c * d //... }
If operator* the return value is a static variable, then the above conditions determine the constant, because the equals sign is the same object on both sides. If you think about using an array of static variables to store the return value, then I can't spit out the slot ...
Struggling with this many, let's return to an object:
inline Const Rational operator*(Const Rational& LHS, Const Rational& RHS){ return Rational(LHS.N*RHS.N, LHS.D*RHS.D);}
In fact, the cost of copy construction returns is not that high, and the C + + standard allows the compiler to make some optimizations that the customer is not aware of (without changing observable behavior). In many cases, the return value is not refactored and copy constructed.
never return a reference to a local object or a pointer to a heap space, or a pointer or reference to a local static object if the customer needs more than one return object. Item 4: Ensure that the initialization of a variable indicates that it is reasonable to return a reference to a local static object for singleton mode.
Unless noted, this blog article is original, reproduced please link to the form of this article address: http://harttle.com/2015/08/18/effective-cpp-21.html
Copyright NOTICE: This article is for bloggers original articles, reproduced please attach the original link.
Item 21: Do not return a reference effective C + + Note When you need to return an object