条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
先看第一种情况:返回一个局部对象的引用。它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的。也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的。所谓生命空间,是指它们所在的函数体。当函数返回时,程序的控制离开了这个空间,所以函数内部所有的局部对象被自动销毁。因此,如果返回局部对象的引用,那个局部对象其实已经在函数调用者使用它之前被销毁了。
第二种情况:返回函数内部用new初始化的指针的引用
inline const rational& operator*(const rational& lhs,
const rational& rhs)
{
// create a new object on the heap
rational *result =
new rational(lhs.n * rhs.n, lhs.d * rhs.d); // return it
return *result;
}
为了在程序中避免内存泄漏,就必须确保对每个用new产生的指针调用delete,但是,这里的问题是,对于这个函数中使用的new,谁来进行对应的delete调用呢?
第一,大家都知道,程序员这类人是很马虎的。这不是指你马虎或我马虎,而是指,没有哪个程序员不和某个有这类习性的人打交道。想让这样的程序员记住无论何时调用operator*后必须得到结果的指针然后调用delete,这样的几率有多大呢?也是说,他们必须这样使用operator*:
const rational& four = two * two; // 得到废弃的指针;
// 将它存在一个引用中
... delete &four; // 得到指针并删除
这样的几率将会小得不能再小。记住,只要有哪怕一个operator*的调用者忘了这条规则,就会造成内存泄漏。即返回函数内部用new初始化的指针的引用,容易被忘记初始化
返回废弃的指针还有另外一个更严重的问题,即使是最尽责的程序员也难以避免。因为常常有这种情况,operator*的结果只是临时用于中间值,它的存在只是为了计算一个更大的表达式,此时无法delete。例如:
rational one(), two(), three(), four();
rational product; product = one * two * three * four;
product的计算表达式需要三个单独的operator*调用,以相应的函数形式重写这个表达式会看得更清楚:
product = operator*(operator*(operator*(one, two), three), four);
是的,每个operator*调用所返回的对象都要被删除,但在这里无法调用delete,因为没有哪个返回对象被保存下来。
条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用的更多相关文章
- C++ //拷贝构造函数调用时机//1.使用一个已经创建完毕的对象来初始化一个新对象 //2.值传递的方式给函数参数传值 //3.值方式返回局部对象
1 //拷贝构造函数调用时机 2 3 4 #include <iostream> 5 using namespace std; 6 7 //1.使用一个已经创建完毕的对象来初始化一个新对象 ...
- 关于C++函数返回局部对象的详细分析
以前一直挺好奇的,C++是怎么在函数内返回一个局部对象的.因为按照我之前的想法,函数返回一个基本类型的值是通过存放到ecx实现的(关于浮点不了解),但是局部对象又是比较大的,很明显不能使用寄存器作为通 ...
- c/c++不能返回局部对象和局部变量的指针或引用解释
在编写c/c++代码时,调用函数的书写让程序变得整洁易读,但是调用函数的返回值(局部变量的返回值,变量,结构体,数组等)也有注意事项.c/c++严禁返回局部变量的指针或引用. 其实函数的返回值的规则非 ...
- C++对象内存布局,this指针,对象作为参数,作为返回值
class TestClass { public: void setNum(int num) { m_num1 = num; } int getNum() { return m_num1; } pri ...
- 【C++对象模型】函数返回C++对象的问题
在深入C++对象模型中,对于形如 CObj obj1 = Get(obj2); 的形式,编译器会在将其改变为如下 Get(obj, CObj& obj1); 将赋值操作符左边的变量作为函数的 ...
- 读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
1. 问题的提出:要求函数返回对象时,可以返回引用么? 一旦程序员理解了按值传递有可能存在效率问题之后(Item 20),许多人都成了十字军战士,决心清除所有隐藏的按值传递所引起的开销.对纯净的按引用 ...
- 条款21: 必须返回对象时,不要强行返回对象的reference
总结: 绝不要返回一个local栈对象的指针或引用:绝不要返回一个被分配的堆对象的引用:绝不要返回一个静态局部对象(为了它,有可能同时需要多个这样的对象的指针或引用). 条款4中给出了“在单线程环境中 ...
- 条款21:必须返回对象object时,不要返回其引用reference
如下为一个有理数类,其中包含一个用来计算乘积的函数: #include <iostream> using namespace std; class Rational { public: R ...
- 【21】必须返回对象时,别妄想返回器reference
1.考虑有理数Rational,有个友元操作符*,返回Rational对象.返回对象,导致临时对象的构造,析构.效率低,因此会想返回方法内局部对象的引用,这种方法不可行.为什么? 2.调用方法是在st ...
随机推荐
- python获取主机名和用户名
import socketimport getpassuser_name = getpass.getuser() # 获取当前用户名hostname = socket.gethostname() # ...
- 372 Super Pow 超级次方
你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出.示例 1:a = 2b = [3]结果: 8示例 2:a = 2b = [1,0]结果: 102 ...
- ibatis入门教程一
这几天研究ibatis玩,参考一篇贴子进行安装配置:蓝雪森林 选择这个帖子来跟随配置是因为这个帖子看着比较干净,但是我仍旧在配置得过程中出现了好几个问题,所以我决定在这个帖子的基础上将更多细节加上,做 ...
- js实现浮动框跟随页面滚动,最后停留在原来位置
左边悬浮的二维码会跟随页面向上或者向下滚动,最后停留在原来的位置. <div style="background:red; width:1000px; height:7000px; m ...
- 2057. [ZLXOI2015]殉国
★☆ 输入文件:BlackHawk.in 输出文件:BlackHawk.out 评测插件 时间限制:0.05 s 内存限制:256 MB [题目描述] 正义的萌军瞄准了位于南极洲的心灵 ...
- Asp.net MVC中文件上传的参数转对象的方法
参照博友的.NET WebApi上传文件接口(带其他参数)实现文件上传并带参数,当需要多个参数时,不想每次都通过HttpContext.Request.Params去取值,就针对HttpRequest ...
- python对象以及pickle腌制
#python对象 1.什么是python的对象 2.详解pickle腌制 1.什么是python的对象 Python的内置的对象类型主要有数字.字符串.列表.元组.字典.集合等等.其实,在pytho ...
- 【Python-2.7】换行符和制表符
在Python中换行符“\n”表示接下来的内容将会换到下一行显示,制表符“\t”表示下面的内容显示时在前面留出空白,如打印如下内容: Dear: I love you forever! 上面的一段话分 ...
- tomcat日志详释
1.tomcat的日志分类: 一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息 . 二是访问日志信息,它记录的访问的时间,IP ,访问的资料等相关信息. 2.tomcat的日志目 ...
- arx移植 及预处理器
来源:http://bbs.mjtd.com/thread-102486-1-1.html 另,ObjectARX编程参考:http://bbs.mjtd.com/forum-14-1.html 如果 ...