条款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 ...
随机推荐
- 全面学习ORACLE Scheduler特性(3)使用Programs
二.使用Programs 在论坛中偶尔见过有人讨论如何在ORACLE中执行操作系统命令,或是ORACLE数据库外的应用.应该说在9i及之前的版本中,虽然说并非完全无法实现(其实还是有多种方式能够变相实 ...
- 专题十二:实现一个简单的FTP服务器
引言: 在本专题中将和大家分享如何自己实现一个简单的FTP服务器.在我们平时的上网过程中,一般都是使用FTP的客户端来对商家提供的服务器进行访问(上传.下载文件),例如我们经常用到微软的SkyDriv ...
- LN : JSON (利用C++实现JSON)
Appreciation to our TA, 王毅峰, who designed this task. 问题描述 JSON, JavaScript Object Notation,is an fle ...
- C++ const学习
概念 const就是为了直接表达“不变化的值”这一概念.也就是说该值只可读,不可直接写. 由于不可以修改,所以const常量在声明的时候必须初始化 const int a; //error exter ...
- Selenium基于Python web自动化测试框架 -- PO
关于selenium测试框架首先想到的就是PO模型,简单说下PO模型 PO模型的概念和理解: PO就是一个设计思想,将代码以页面为单位进行组织,针对这个页面上的所有信息.相关操作都放到一个类中,从而使 ...
- text-shadow的用法详解
1.兼容性:text-shadow 和 box-shadow 这两个属性在主流现代浏览器上得到了很好的支持( > Chrome 4.0, > Firefox 3.5, > Safar ...
- ElasticSearch 安装使用
安装: 1.下载ElasticSearch.解压到相关文件夹 2.运行elasticsearch.bat,启动程序 3.在浏览器输入:http://localhost:9200/,显示相关Es内容即安 ...
- 安装mask-rcnn问题汇总
1. I download file from https://github.com/waleedka/coco. Then I placed the file in Mask_RCNN-master ...
- POJ_2239_Selecting Courses
题意:一周上7天课,每天12节课,学校最多开设300节不同的课,每周每种课可以只有一个上课时间或者多个上课时间(上课内容一样),问一周最多可以选多少节课. 分析:二分图最大匹配,将一周84个时间点和可 ...
- radiobutton group
1. 环境:VS2010 2. 分组 将radio1.radio2.radio3分为1组,radio4.radio5分为另一组: 方法:设置 radio1 的 属性: group.tabstop ...