在返回值拒绝——reference
在上一篇博客中,我们介绍了简单地使用值传递带来的种种麻烦,相信有些朋友会一心一意将其斩草除根,但是当返回值也使用了引用的时候,麻烦就来了。
依然来个简答的例子
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的更多相关文章
- C#7.0--引用返回值和引用局部变量
一.在C#7.0以上版本中,方法的返回值可以通过关键字ref指定为返回变量的引用(而不是值)给调用方,这称为引用返回值(Reference Return Value,或ref returns): 1. ...
- c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询
天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. 不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...
- GetLastError()函数返回值及含义
GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置.函数并无必要设置上一次错误信息,所以即使一次GetLastError调用返回的是零值, ...
- 常量函数、常量引用参数、常量引用返回值[C++]
1. 关于常量引用正像在C语言中使用指针一样,C++中通常使用引用 有一个函数... foo()并且这个函数返回一个引用...... & foo()...., 一个指向位图(Bitmap)的引 ...
- 深入理解PHP内核(十二)函数-函数的定义、传参及返回值
原文链接:http://www.orlion.ga/344/ 一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; ...
- 深入理解PHP内核(六)函数的定义、传参及返回值
一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; } 1.词法分析 在Zend/zend_language_scann ...
- for_each()的返回值
有三种办法可以从“运用了function object”的算法中获取“结果”或“反馈”: 1.在外部持有状态,并让function object指向它: 2.以by reference方式传递func ...
- C++ 中的返回值
C++中大致有三种返回值:值拷贝(副本),值引用和指针,返回什么类型的值要根据当时情况而定. 如果返回的是大型对象的副本,那么在每一次的函数调用后返回,都会调用该对象类型的拷贝构造函数构造一个新的副本 ...
- 条款21: 必须返回对象时,不要强行返回对象的reference
总结: 绝不要返回一个local栈对象的指针或引用:绝不要返回一个被分配的堆对象的引用:绝不要返回一个静态局部对象(为了它,有可能同时需要多个这样的对象的指针或引用). 条款4中给出了“在单线程环境中 ...
随机推荐
- web框架们~Django~Flask~Tornado
1.web框架本质 2.Django 3.Flask 4.Tornado
- JAVA参数没有引用传递,只有值传递
原文章地址:http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性, ...
- Idea的注入和自动编译配置
实时编译: 第二个(防止编译时Autowired报错): 修改成:
- android 第三方框架
1.视频:jcvideoplayer 2.圆角:cardview 3.圆形头像:circleimageview 4.加载网络图片:universalimageloader 5.网络请求:xutils ...
- elasticsearch-hadoop使用
elasticsearch-hadoop是一个深度集成Hadoop和ElasticSearch的项目,也是ES官方来维护的一个子项目,通过实现Hadoop和ES之间的输入输出,可以在Hadoop里面对 ...
- Oracle监控的关键指标
1.监控事例的等待 select event, , , )) "Prev", , , )) "Curr", count(*) "Tot" f ...
- 202-React.Component组件、生命周期
一.概述 React可以将组件定义为类或函数.定义为类的组件当前提供了更多的功能.要定义React组件类,您需要扩展React.Component: class Welcome extends Rea ...
- centos7 安装python3.6 及模块安装演示
目录: 下载python3.6 安装python3.6的依赖 编译安装 更改链接 更改yum脚本的python依赖 修改gnome-weaktool配置文件 修改urlgrabber配置文件 1.下载 ...
- python模块之subprocess模块
简述 subprocess意在替代其他几个老的模块或者函数,比如:os.system os.spawn* os.popen* popen2.* commands.*subprocess最简单的用法就是 ...
- The same month as the adidas NMD Singapore is releasing
Earlier this December 2017, the inaugural adidas NMD Singapore silhouette released in the first colo ...