C++运算符重载,+-*/的重载,返回值为什么是对象而不是对象的引用?而流操作符<< 和 >> 却返回的是引用?

 我来答
hyfatbd
推荐于2016-02-14 · TA获得超过237个赞
知道小有建树答主
回答量:149
采纳率:100%
帮助的人:114万
展开全部

原因是:

  1. +,-,*等返回不了引用,比如+运算符,可以如下重载(为了简单,假设A 只有int x;int y)

    A operator+(A a,A b) {A sum;   sum.x=a.x+b.x; sum.y=a.y+b.y;   return sum; }

    分析不能用引用的原因: 函数传入了两个参数a,b,并且+只能传入两个参数(c++不允许自己创造运算符),这样就限定了和sum不能作为参数传入,所以sum只能是一个函数里的临时变量,但是临时变量在函数结束时是要销毁的,那么函数调用玩,sum就没有了, 如果返回引用,引用源都已经没有了,还怎么引用,引用哪里的东西呢??

    所以不能引用。

  2. <<,>>可以返回引用,而且不返回引用也是编译不过的,貌似是c++的要求。可以不用引用试一试,有的编译器会出来一个ios_base.h文件,就是想告诉你用引用。

    返回引用也是可以解释的。 比如还是上面的A类型,如下

    ostream& operator<<(ostream& out, const A& a) { out<<A.x<<' '<<A.y<<endl; retrun out;}

    能返回引用,首先是因为out是作为参数传入的,不是函数的临时变量,函数结束时它仍然存在,这样就可以引用了。  再者,返回引用效率高,不用拷贝一个新的,直接返回它自己。 而且,返回引用有助于连着调用。比如cout<<a<<b<<c<<d,为什么可以连着写?其实<<也是函数,为什么我们平时的函数一般不能连着写?如a.xx().xx().xx.()这样调用三个xx()。这也体现了引用的作用。 对于cout<<a<<b<<c<<d;就是

    operator<<(operator<<(operator<<(operato<<(cout,a),b),c),d);

    从左到右先执行cout<<a执行完了后返回cout的引用,就是cout本身,那么原式变为cout<<b<<c<<d; 紧接着这行cout<<b执行完再次返回cout........这样就把a,b,c,d依次作用到了cout,我们于是看到abcd连续输出了。

追问
如你所说,cout<<a<<b<<c<<d;谭浩强说,先执行cout<<a,返回一个输出流对象(引用),然后这个新的cout对象(引用)又执行<<b,然后又返回一个新的cout对象(引用),直到输出完成。每输出一次,就返回一个新的输出流对象(引用),那每次输出流对象cout有啥不同。
追答

一般可以认为第一次执行完cout直接将a输出到了屏幕,cout本身没有变化,然后执行b......

但是具体情况不是这样的。这要看c++的IO具体是怎么设计的。执行一次cout<<a并不一定直接将a输出到屏幕,而是将a转到IO的缓冲区,具体什么时候将a输出到屏幕要看系统什么时候有时间和c++的IO具体是怎么实现的。 系统掌握着消息队列,每次从里面抽取一条消息执行,因为CPU效率很高,我们感觉程序是连续运行的,其实不连续。对于多核处理器来说可以发生真实的同时执行几个程序。

要强制系统将数据输出到屏幕上,可以“刷新”一下,比如用cout<<endl;就是打一个换行,再刷新缓冲区,刷到屏幕上。


对于评论区的两点,解释一下:

  1. 重载<<流输出运算符,我是用于一个自定义类与ostream类,不是重载<<的移位运算等,不用做其他用法。  在我的编译器上不通过(VS2012和DEV c++都编译不通过)

  2. 我举得例子有错误,为了简便直接写的,现在发现是错的。因为都是A的对象相加,如果有两个参数,那么应该是友元函数,frined ......, 如果一个参数,可以声明为成员函数。

    至于为什么返回引用也正常,这是由于:

    “函数返回的临时变量是放在堆栈上的,所以返回来后如果你没有调用其他的函数,那么这个临时变量在依然保存在堆栈中,是可以被引用的。
    因为这时堆栈并没有被破坏。但是一旦调用其他函数后堆栈被破坏了,那个返回值就没有用了”

    摘自“正心修身齐家治国平天下”的百度空间,可以看一下。

    即使这样编译器也会给警告(WARNING),不建议这么写

心中风情4
2013-09-30 · TA获得超过2247个赞
知道大有可为答主
回答量:1779
采纳率:66%
帮助的人:1084万
展开全部
C++ Primer里有解释的,一切是为了保持与内置操作的一致性,并非一定要这样,只是这样做才是规范的,还是那句话保持与内置操作的一致性!!!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友cd8541ae4
2013-09-30 · TA获得超过264个赞
知道小有建树答主
回答量:126
采纳率:100%
帮助的人:114万
展开全部
你可以认为在函数中产生了新的对象,并且需要返回的就是新产生的这个对象,就返回对象;
如果在函数中没有产生新的对象,需要返回的是调用函数之前就存在的对象,就返回引用。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
N_cute
2013-09-30 · TA获得超过1084个赞
知道答主
回答量:140
采纳率:0%
帮助的人:83.7万
展开全部
如果返回的是引用,那么a+b=5这样的表达式你说怎么理解?
返回怎样的值,是基于需求考虑的,+-*/的结果,只需要临时使用,因此,返回对象就行了,至于返回引用,可以一方面可以继续处理,另一方面,没有复制拷贝的代价,更高效。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式