return value of operator overloading in C++
来源:互联网 发布:幼儿园美工室活动计划 编辑:程序博客网 时间:2024/05/16 15:07
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 underneath rule of that? Especially at the case when you can use the operator continuously, such as cout<<x<<y
.
For example, when implementing a + operation "string + (string)". how would you return the return value, by ref or by val.
5 Answers
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).
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;}
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.
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.
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.
- return value of operator overloading in C++
- Operator Overloading in Swift Tutorial
- C++.Homework. Operator overloading.01
- C++.Homework. Operator overloading.02
- thinking in c++ 读书笔记---operator overloading
- Overloading Functions in C
- Operator Overloading
- Operator overloading
- Operator Overloading
- Return to the Basic - 运算符重载 (Operator Overloading )
- C++. Operator overloading.Fraction's operation
- The return value of "mktime" in different time zone
- C++.Experiment 4.Operator overloading(& date plus days)
- Unable to find a value for "tStatus" in object of class org.entity.Passport using operator "."
- 14.2.2 Operator overloading
- C# Operator Overloading
- What is operator overloading
- Simple operator overloading
- Getting Started with WebRTC
- iOS 各种修饰符的区别汇总
- 利用 SysRq 键排除和诊断系统故障
- C/C++__字符串的结束符“\0”到底是什么
- hdoj1106排序(sort)
- return value of operator overloading in C++
- Best Time to Buy and Sell Stock II
- JNDI访问LDAP目录服务
- 标准Http协议支持六种请求方法
- iOS Notification 通知中心
- Maven核心概念之仓库,生命周期与插件
- python安装
- E - Easy Task --- (fisrt qualifying)
- 生成MyEclipse6.5&7.5&8.0注册码的java源码
<<
does not modify the existing value. It's just a left-shift operator. It's the stream interface breaking the rules. – kennytm Feb 25 '10 at 20:13operator<<
) where the overload is implemented as a non-member. – Tyler McHenry Feb 25 '10 at 20:13++
produces a new value, after all. How about keep the second half of the sentence, and add "All other values should return by value." – thebretness Feb 25 '10 at 20:14