EC笔记:第4部分:21、必须返回对象时,别返回引用
使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用。
如下:
struct St {
int a;
};
St &func(){
St t;
return t;
}
在返回t以后,t会被销毁,但是它的引用还在外面被使用,这样的操作是不可预料的。
那么,我们返回一个指针如何?
struct St {
int a;
};
St*&
func(){
St *t=new St;
return t;
}
这样,从语法角度上来说没有问题,但是,在堆上分配的内存该有谁释放呢???
那么,再试试静态变量:
struct St {
int a;
};
St&
func(){
static St t;
return t;
}
这样会存在什么问题呢?
问题就是,某些调用下可能得不到正确的结果:
例如我们对此程序做一下修改:
#include <iostream>
#include <cstdlib>
using
namespace std;
struct St {
int a;
};
St&
func(){
static St t;
t.a=rand();
return t;
}
int
main(int argc,
char
*argv[])
{
St &t=func();
cout<<t.a<<endl;
func();
cout<<t.a<<endl;
}
输出的结果是:
41
18467
我们没有对t,使用赋值操作,但是t的值却变了。这是因为这里的t相当于一个全局变量,我们再次调用func()时,就会改变t的值。
那么看来只能返回值了:
struct St {
int a;
};
St func(){
St t;
t.a=rand();
return t;
}
但是这样并不好,会多次调用构造和析构函数。怎样做到效率高而且又正确呢?
struct St {
int a;
};
St func(){
return St{rand()};
}
编译器会我们省掉一些多余的构造函数与析构函数的调用。
什么时候该使用值传递?什么时候该使用引用传递?这主要取决于具体的需求。但是绝对不要返回一个局部变量的指针或引用,也不要返回一个局部静态变量的指针或引用。
EC笔记:第4部分:21、必须返回对象时,别返回引用的更多相关文章
- Effective C++ -----条款21:必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...
- 【21】必须返回对象时,别妄想返回器reference
1.考虑有理数Rational,有个友元操作符*,返回Rational对象.返回对象,导致临时对象的构造,析构.效率低,因此会想返回方法内局部对象的引用,这种方法不可行.为什么? 2.调用方法是在st ...
- 条款21: 必须返回对象时,不要强行返回对象的reference
总结: 绝不要返回一个local栈对象的指针或引用:绝不要返回一个被分配的堆对象的引用:绝不要返回一个静态局部对象(为了它,有可能同时需要多个这样的对象的指针或引用). 条款4中给出了“在单线程环境中 ...
- 条款21:必须返回对象时,别妄想返回其reference(Don't try to return a reference when you must return an object)
NOTE: 1.绝不要返回pointer或reference 指向一个local stack 对象,或返回reference 指向一个heap-allocated对象,或返回pointer 或refe ...
- 必须返回对象时,别妄想返回其reference 【Effective C++ 条款21】
class Rational { public: Rational(, ) : n(numerator), d(denominator) { printf("Rational Constru ...
- [Effective C++ --021]必须返回对象时,别妄想返回其reference
引言 在条目20中,我们知道了值传递和引用传递的效率问题,因此在设计程序时,我们可能就尽可能来返回引用而不是值. 可是,可能会犯下面的一些错误:传递一些引用指向其实并不存在的对象. 第一节:返回临时变 ...
- EC笔记,第一部分:4.确定对象初始化
04.确定对象初始化 将对象初始化,C++反复无常,所以在使用前应该手动初始化 1.分清赋值与初始化 以下例子: class test{ public: int a; test(){ a=0;//赋值 ...
- Java学习笔记13---如何理解“子类重写父类方法时,返回值若为类类型,则必须与父类返回值类型相同或为其子类”
子类重新实现父类的方法称重写:重写时可以修改访问权限修饰符和返回值,方法名和参数类型及个数都不可以修改:仅当返回值为类类型时,重写的方法才可以修改返回值类型,且必须是父类方法返回值的子类:要么就不修改 ...
- 读书笔记_Effective_C++_条款二十一:当必须返回对象时,别妄想返回其reference
在栈空间的临时成员变量在函数生命期结束后无法传出 friend A& operator*(const A& a, const A& b) { A temp; temp.data ...
随机推荐
- 用神奇的currentColor制作简洁的颜色动画效果
先上一个兼容性总结图:老版本ie可以直接用复杂方法了,套用某表情包的话: 2016年了,做前端你还考虑兼容IE6?你这简直是自暴自弃! 好了,知道了兼容性,我们可以放心的使用了. 在CSS3中扩展了 ...
- 免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
前面介绍了六种.NET组件,其中有一种组件是写文件的压缩和解压,现在介绍另一种文件的解压缩组件SharpZipLib.在这个组件介绍系列中,只为简单的介绍组件的背景和简单的应用,读者在阅读时可以结合官 ...
- Asp.net Core准备工作
1.安装环境 安装.Net Core SDK 安装VS2015 Update3 安装DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe 2.新建Core工程 项 ...
- sql的那些事(一)
一.概述 书写sql是我们程序猿在开发中必不可少的技能,优秀的sql语句,执行起来吊炸天,性能杠杠的.差劲的sql,不仅使查询效率降低,维护起来也十分不便.一切都是为了性能,一切都是为了业务,你觉得你 ...
- C#泛型详解(转)
初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...
- 彻底搞懂Javascript的“==”
本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- jmeter之线程组的使用
线程组 在使用jmeter性能测试时,我们都得先添加个线程组,右键testplan-->添加-->Threads-->线程组.在线程组下执行. 问题:为了能够让jmeter在做性能测 ...
- 使用Xamarin开发iOS7应用时隐藏StatusBar方法
在iOS7之前如果需要隐藏StatusBar,比较简单,直接在AppDelegate.cs中使用如下代码就可以进行隐藏: UIApplication.SharedApplication.StatusB ...
- .Net Core 系列:1、环境搭建
前言: 2016年6月28日微软宣布发布 .NET Core 1.0.ASP.NET Core 1.0 和 Entity Framework Core 1.0. .NET Core是微软在两年前发起的 ...