C++ 重载运算符返回值 和 返回引用的原因
原因是:
+,-,*等返回不了引用,比如+运算符,可以如下重载(为了简单,假设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就没有了, 如果返回引用,引用源都已经没有了,还怎么引用,引用哪里的东西呢??
所以不能引用。
<<,>>可以返回引用,而且不返回引用也是编译不过的,貌似是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;就是打一个换行,再刷新缓冲区,刷到屏幕上。
对于评论区的两点,解释一下:
重载<<流输出运算符,我是用于一个自定义类与ostream类,不是重载<<的移位运算等,不用做其他用法。 在我的编译器上不通过(VS2012和DEV c++都编译不通过)
我举得例子有错误,为了简便直接写的,现在发现是错的。因为都是A的对象相加,如果有两个参数,那么应该是友元函数,frined ......, 如果一个参数,可以声明为成员函数。
至于为什么返回引用也正常,这是由于:
“函数返回的临时变量是放在堆栈上的,所以返回来后如果你没有调用其他的函数,那么这个临时变量在依然保存在堆栈中,是可以被引用的。
因为这时堆栈并没有被破坏。但是一旦调用其他函数后堆栈被破坏了,那个返回值就没有用了”摘自“正心修身齐家治国平天下”的百度空间,可以看一下。
即使这样编译器也会给警告(WARNING),不建议这么写
===================以上摘自百度https://zhidao.baidu.com/question/917635728677386659.html
C++ 重载运算符返回值 和 返回引用的原因的更多相关文章
- shell函数(调用、返回值,返回值获取)
Shell函数返回值,常用的两种方式:return,echo 1) return 语句shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回.示例1: [devadmin@swa ...
- scala:函数作为值或参数进行传递、作为返回值进行返回
@ 目录 函数可以作为值进行传递 函数可以作为参数进行传递 函数可以作为返回值进行返回 什么是匿名函数 函数可以作为值进行传递 语法var f = 函数名 _ 如果明确了变量的数据类型,那么下划线可以 ...
- 【C/C++】引用&的含义/语法/作为函数参数/函数返回值/本质/常量引用
含义 引用不产生副本,只是给原变量起了别名. 对引用变量的操作就是对原变量的操作. 基本语法 数据类型 &别名 = 原名 e.g. int a = 10; int &b = a; // ...
- Java学习笔记14---this作为返回值时返回的是什么
有时会遇到this作为返回值的情况,那么此时返回的到底是什么呢? 返回的是调用this所处方法的那个对象的引用,读起来有点绕口哈,有没有想起小学语文分析句子成份的试题,哈哈. 一点点分析的话,主干是& ...
- std::vector<bool> 在 auto 推断下的返回值是 bool & 引用
转自: https://www.cnblogs.com/hustxujinkang/p/5218148.html //////////// std::vector<bool> featur ...
- python操作mysql数据-执行语句返回值直接返回字典类型
fetchall()将结果放在二维数组里面,每一行的结果在元组里面 import pymysql def export(table_name): conn =pymysql.connect(host ...
- $.extend(obj1,obj2...,objN)小结 扩展obj1属性,有返回值,返回第一个被扩展后的对象
<script> var obj1 = { name:'liu', age:'24' } var obj2 = { name:'jinyu', sex:'m ...
- Python3基础 函数 未指定返回值,返回NONE
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- C#7.0--引用返回值和引用局部变量
一.在C#7.0以上版本中,方法的返回值可以通过关键字ref指定为返回变量的引用(而不是值)给调用方,这称为引用返回值(Reference Return Value,或ref returns): 1. ...
随机推荐
- Parse发布Bolts,一个面向iOS和Android的底层库集合
转载自:http://www.infoq.com/cn/news/2014/02/parse-announces-bolts 数月前,Parse被Facebook收购.最近,它开源了一个面向iOS和A ...
- TextBox光标定位到文本末尾
private void RichTextBox1_TextChanged(object sender, EventArgs e) { this.richTextBox1.Select(richTex ...
- Flink 之 写入数据到 ElasticSearch
前面 FLink 的文章中我们已经介绍了说 Flink 已经有很多自带的 Connector. 1.<从0到1学习Flink>—— Data Source 介绍 2.<从0到1学习F ...
- java项目代码上线
java项目代码上线 1:java项目代码上线架构图 ip地址及主机名规划 10.0.0.11 deploy 10.0.0.12 tomcat-web01 10.0.0.13 git.oldboy ...
- Gradle vs. Maven: Performance, Compatibility, Speed, & Builds
Gradle vs. Maven: Performance, Compatibility, Speed, & Buildshttps://stackify.com/gradle-vs-mave ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_38、源码编译安装Redis4.x
笔记 2.源码编译安装Redis4.x 简介:使用源码安装Redis4.x和配置外网访问 1.快速安装 https://redis.io/download#installation ...
- disruptor 单生产者多消费者
demo1 单生产者多消费者创建. maven 依赖 <!-- https://mvnrepository.com/artifact/com.lmax/disruptor --> < ...
- 贪心:leetcode 870. Advantage Shuffle、134. Gas Station、452. Minimum Number of Arrows to Burst Balloons、316. Remove Duplicate Letters
870. Advantage Shuffle 思路:A数组的最大值大于B的最大值,就拿这个A跟B比较:如果不大于,就拿最小值跟B比较 A可以改变顺序,但B的顺序不能改变,只能通过容器来获得由大到小的顺 ...
- MyBatis原理总结(代码实现流程)
我们在实际开发中,越简单越好,所以都是采用不写Dao实现类的方式.不管是使用xml还是直接配置. 但是MyBatis是支持写Dao实现类的 注意sqlSession是这里面的一个灵魂,有很多执行api ...
- Ubuntu18.04 instsall XMind_8 and crack
1.dowload XMind_8 linux install zip wget https://www.xmind.cn/xmind/downloads/xmind-8-update8-linux. ...