return value of operator overloading in C++

前端 未结 5 2013
逝去的感伤
逝去的感伤 2020-11-29 18:19

I have a question about the return value of operator overloading in C++. Generally, I found two cases, one is return-by-value, and one is return-by-reference. So what\'s the

相关标签:
5条回答
  • 2020-11-29 18:30

    Depending on the operator you may have to return by value.

    When both can be used though, like in operator+= you could consider the following:

    • If your objects are immutable it's probably better to return by value.
    • If your objects are mutable it's probably better to return by reference.
    0 讨论(0)
  • 2020-11-29 18:31

    To attempt an answer to your question regarding strings, the operator+() for strings is almost always implemented as a free (non-member) function so that implicit conversions can be performed on either parameter. That is so you can say things like:

    string s1 = "bar";
    string s2 = "foo" + s1;
    

    Given that, and that we can see that neither parameter can be changed, it must be declared as:

    RETURN_TYPE operator +( const string & a, const string & b );
    

    We ignore the RETURN_TYPE for the moment. As we cannot return either parameter (because we can't change them), the implementation must create a new, concatenated value:

    RETURN_TYPE operator +( const string & a, const string & b ) {
        string newval = a;
        newval += b;    // a common implementation
        return newval;
    }
    

    Now if we make RETURN_TYPE a reference, we will be returning a reference to a local object, which is a well-known no-no as the local object don't exist outside the function. So our only choice is to return a value, i.e. a copy:

    string operator +( const string & a, const string & b ) {
        string newval = a;
        newval += b;    // a common implementation
        return newval;
    }
    
    0 讨论(0)
  • 2020-11-29 18:38

    Usually you return by reference in an operation that changes the value of the things it's operating on, like = or +=. All other operations are return by value.

    This is more a rule of thumb, though. You can design your operator either way.

    0 讨论(0)
  • 2020-11-29 18:51

    If you want your operator overload to behave like the built-in operator, then the rule is pretty simple; the standard defines exactly how the built-in operators behave and will indicate if the result of a built-in is an rvalue or an lvalue.

    The rule you should use is:

    • if the built-in operator returns an rvalue then your overload should return a reference
    • if the built-in returns an lvalue then your overload should return a value

    However, your overload isn't required to return the same kind of result as the built-in, though that's what you should do unless you have a good reason to do otherwise.

    For example, KennyTM noted in a comment to another answer that the stream overloads for the << and >> operators return a reference to the left operand, which is not how the built-ins work. But the designers of the stream interface did this so stream I/O could be chained.

    0 讨论(0)
  • 2020-11-29 18:54

    Some operators return by value, some by reference. In general, an operator whose result is a new value (such as +, -, etc) must return the new value by value, and an operator whose result is an existing value, but modified (such as <<, >>, +=, -=, etc), should return a reference to the modified value.

    For example, cout is a std::ostream, and inserting data into the stream is a modifying operation, so to implement the << operator to insert into an ostream, the operator is defined like this:

    std::ostream& operator<< (std::ostream& lhs, const MyType& rhs)
    {
      // Do whatever to put the contents of the rhs object into the lhs stream
      return lhs;
    }
    

    This way, when you have a compound statement like cout << x << y, the sub-expression cout << x is evaluated first, and then the expression [result of cout << x ] << y is evaluated. Since the operator << on x returns a reference to cout, the expression [result of cout << x ] << y is equivalent to cout << y, as expected.

    Conversely, for "string + string", the result is a new string (both original strings are unchanged), so it must return by value (otherwise you would be returning a reference to a temporary, which is undefined behavior).

    0 讨论(0)
提交回复
热议问题