C + + must return to the object, do not expect to return to its reference---"Effective C + +" __c++

Source: Internet
Author: User
clause 21: When an object must be returned, do not attempt to return to its reference

On the blog we talked about the pass-by-value efficiency is particularly low, in addition to certain circumstances, as far as possible in the transfer of parameters to use Pass-by-reference-to-const, so, some small partners to go to an extreme, Firm pursuit of Pass-by-reference purity, so that the return value also want to set as a reference, but the goose extremes, not too desperate to pursue extreme. Let's take a look at some examples and poke the mist out of your little friends.

Class rational{public
:
    Rational (int numerator=0,int denominator=1);
    ...
Private:
    int n,d;
    Friend Const Rational operator* (const rational& lhs,const rational& RHS);//Here Please do not focus too much on the return value is const    , which is to avoid ( (a*b) =c) Such hand mistake, where a,b,c are rational objects
};

Here we see that the value returned by the program is rational, so that it does not duplicate the return value and consumes memory. Is there any way to do that?
Do you want to declare it as a return value reference.
1 Create objects in stack space
Please refer to the following code:

Const rational& operator* (const rational& lhs,const rational& RHS) {
    Rational result (lhs.n*rhs,lhs.d* RHS.D);
    return result;
}

In this way, there is no need to replicate the return value, the efficiency is not high. Sorry, old iron, it's wrong to think so, notice what result is, the local object, but the operator* function call is over. Early release, at this time rational& 's address is nothing, just a wreck, if the basic type, such as the object of the destructor, the good luck may exist for some time, so this method is wrong.
2 creating objects in heap space

Const rational& operator* (const rational& lhs,const rational& RHS) {
    rational* result=new Rational ( LHS.N*RHS.N,LHS.D*RHS.D);
    return *result;
}

In this case, the thing that does not refer to the returned value is the one in the head. There's nothing wrong with it. It is true that you can return the correct value, however. We created the object in the heap, when to delete it, old iron, delete it. Especially when it's called like this:

Rational w,x,y,z;
W=x*y*z;

This two consecutive calls to the operator* function, so two times using new, also need two times to use the Delete method, but there is no way to delete ah, so this method is still wrong.
3 Declare the static variable as the value of the return reference

Const rational& operator* (const rational& lhs,const rational& RHS) {
    static Rational result;
    Result= ...;
    return result;
}

That's not going to solve the problem. hahaha, old iron, you planted again, C + + pit more go, a little attention to be pit, then this way have what problem.
Multithreading security is problematic;
There may be a problem with the calculated value, so take a look at the following code:

#include <iostream>
#include <string>
using namespace std;
int& hel (int t) {
    static int i = t + 1;
    return i;
}

int main () {
    int i = ten, j = m;
    cout << Hel (i) << "" << Hel (j) << Endl;
    if (hel (i) = = Hel (j)) {
        cout << "true" << Endl;
    }
    else{
        cout << "false" << Endl;
    }
    return 0;
}

The results of the operation are as follows:

We can see that the values are equal at this time, why. Because we return all the values of the static int I, and the internal static is overwritten, we will always see the static "present value", so the two are definitely equal in comparison.

Finally, we realized that if we wanted to return reference to a function such as operator*, it would be possible to implement it in the most extreme way, such as the following:
There may be a few more powerful partners that say we can declare an array inside the function, then return the different index values in the array, which can be implemented in this complex way, so that the array space, size is not determined, while the copy operation is wasting time, constructor destructor call consumes resources, is not worth the candle, Big Brother.

Like operator* this function, our most recommended method is to return the object, rather than desperately return the reference, resulting in the loss or error of the problem.

Const Rational operator* (const rational& lhs,const rational& RHS) {return
    Rational (LHS.N*RHS,LHS.D*RHS.D) ;
}

Summarize:
Never return pointer or reference to a local stack object, or return reference point to a Heap-allocated object, or return to reference or pointer point to local Static object, so that we have to weigh the "return of a reference and return an object", we need to make a careful decision.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.