在上一篇博客中,我们介绍了简单地使用值传递带来的种种麻烦,相信有些朋友会一心一意将其斩草除根,但是当返回值也使用了引用的时候,麻烦就来了。

依然来个简答的例子

class Rational
{
public:
Rational(int numerator = 0,int denominator = 1);
private:
const Rational& operator*(const Rational& lhs,const Rational& rhs);
};

operator的返回值是一个reference。记得那句话吗?“引用是另外一个变量的别名”,那么问题就来了,operator返回的引用是谁的别名。假如我们返回的是一个局部变量,那么这个家伙在函数返回的时候实际上已经不存在了。也就是说,这个时候返回的reference,是“以前的,已经不存在的一个变量的别名”。而假如我们使用一个不存在的东西,我们也将一败涂地。这个时候,我们考虑在heap(堆)上创建一个对象。

const Rational& operator*(const Rational& lhs,const Rational& rhs)
{
Rational *result = new Rational();
return *result;
}

让我们回溯到提醒我们使用引用的原因上:避免太大的消耗。这个主要体现在构造函数与析构函数上,而上述的例子中,很明显我们又回到了解决问题之前,又得付出一个构造函数的代价。但是,更不妥的是,下面这个例子。

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

x * y将会在heap上new Rational()产生一个Rational_1,然后这个Rational_1的引用与z又将会在heap上new Rational()产生一个Rational_2,然后这个Rational_2将会被w持有。在程序结束的时候,我们使用delete w销毁了Rational_2,那么,Rational_1呢?很明显,我们造成了内存泄露。

从上面的描述我们可以发现,不管是在stack或者在heap上,返回一个reference都会受到惩罚。那么函数返回一个对象的正确写法是什么呢?就是”让函数返回一个对象呗“虽然,这有可能给性能造成一定的拖累,但是它能保证这是正确的。

在返回值拒绝——reference的更多相关文章

  1. C#7.0--引用返回值和引用局部变量

    一.在C#7.0以上版本中,方法的返回值可以通过关键字ref指定为返回变量的引用(而不是值)给调用方,这称为引用返回值(Reference Return Value,或ref returns): 1. ...

  2. c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询

    天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. ​ ​不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...

  3. GetLastError()函数返回值及含义

    GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置.函数并无必要设置上一次错误信息,所以即使一次GetLastError调用返回的是零值, ...

  4. 常量函数、常量引用参数、常量引用返回值[C++]

    1. 关于常量引用正像在C语言中使用指针一样,C++中通常使用引用 有一个函数... foo()并且这个函数返回一个引用...... & foo()...., 一个指向位图(Bitmap)的引 ...

  5. 深入理解PHP内核(十二)函数-函数的定义、传参及返回值

    原文链接:http://www.orlion.ga/344/ 一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) {    echo $var; ...

  6. 深入理解PHP内核(六)函数的定义、传参及返回值

    一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; } 1.词法分析 在Zend/zend_language_scann ...

  7. for_each()的返回值

    有三种办法可以从“运用了function object”的算法中获取“结果”或“反馈”: 1.在外部持有状态,并让function object指向它: 2.以by reference方式传递func ...

  8. C++ 中的返回值

    C++中大致有三种返回值:值拷贝(副本),值引用和指针,返回什么类型的值要根据当时情况而定. 如果返回的是大型对象的副本,那么在每一次的函数调用后返回,都会调用该对象类型的拷贝构造函数构造一个新的副本 ...

  9. 条款21: 必须返回对象时,不要强行返回对象的reference

    总结: 绝不要返回一个local栈对象的指针或引用:绝不要返回一个被分配的堆对象的引用:绝不要返回一个静态局部对象(为了它,有可能同时需要多个这样的对象的指针或引用). 条款4中给出了“在单线程环境中 ...

随机推荐

  1. JavaScript高级程序设计第三版学习笔记(一)之数据类型区分详谈

    null.NaN.undefined三者的区别是什么? 在初次接触到JavaScript的时候,傻傻的分不清null.NaN.undefined三者到底区别何在,在实际的项目开发中也因为这个问题而困惑 ...

  2. Hive与ES整合

    https://www.elastic.co/guide/en/elasticsearch/hadoop/current/hive.html 注:添加的第三方jar必须位于namenode下,否则依然 ...

  3. 创建WCF服务的过程

    一.创建控制台WCF工程 1.创建一个控制台工程2.System.ServiceModel的引用3.可创建多个WCF服务,如:IService.cs和Service.cs    顺序:右键->添 ...

  4. in 和 or 的效率问题

    select * from table where col in (2,3,4,5,6) select * from table where col=2 or col=3 or col=4 or co ...

  5. Centos7 Zabbix3.2安装

    实验环境: 阿里云 [zabbix@miyan ~]$ cat /etc/redhat-release CentOS Linux release (Core) 不得不说,官方文档确实强大 1.官方文档 ...

  6. oracle 保留小数位

    方法一:使用to_char的fm格式 to_char(round(data.amount,2),'FM9999999999999999.00') as amount 不足之处是,如果数值是0的话,会显 ...

  7. JOJ1202。重新操刀ACM,一天一练!做个简单的题目温习。

    http://ac.jobdu.com/problem.php?pid=1202 题目描述: 对输入的n个数进行排序并输出. 输入: 输入的第一行包括一个整数n(1<=n<=100).   ...

  8. cocos-lua基础学习(九)spite类学习笔记

    创建精灵 ,) ) layer:addChild( sprite ) ) layer:addChild(BatchNode, , kTagSpriteBatchNode) ,) ) layer:add ...

  9. SQL: coalesce()函数

    ①用途: 将空值替换成其他值 返回第一个非空值 ②表达式: COALESCE是一个函数, (expression_1, expression_2, ...,expression_n)依次参考各参数表达 ...

  10. eclipse如何设置编译后target目录不提交svn服务器

    eclipse设置 windows ->prefrences->team->Ignored Resource 点击Add Pattern  输入    */target/*    等 ...