引言

在条目20中,我们知道了值传递和引用传递的效率问题,因此在设计程序时,我们可能就尽可能来返回引用而不是值。

可是,可能会犯下面的一些错误:传递一些引用指向其实并不存在的对象。

第一节:返回临时变量的引用

假如我们有以下的例子,先看值传递

 class A {
public:
A(int n = , int d = ):n(n),d(d) {}
private:
int n,d;
friend const A operator* (const A& l, const A& r);
};

在operator*系以值传递的方式返回了一个计算结果,联系到条款20,我们自然会想到,那么用引用传递试试。

因为函数返回的是A对象,所以函数创建新对象的方式有2:

1.在stack空间创建

 const A& operator* (const A& l, const A& r) {
A result(l.n * r.n, l.d * r.d);
return result;
}

这样我们避免值传递的调用构造和析构函数,可是result是个临时变量,在函数推出前就被销毁了。任何对这个函数的调用都会是无意义的行为。

2.在heap空间创建

 const A& operator* (const A& l, const A& r) {
A* result = new A(l.n * r.n, l.d * r.d);
return *result;
}

这样解决了上面临时变量的问题。可是,这个new出来的对象什么时候被释放呢?

就算我们调用A的时候很谨慎,但还是避免不了出错,比如

 A w,x,y,z;
w = x * y * z; // 实际与operator*(operator*(x, y), z)相同

这里同一个语句例调用了两次operator*,因此两次使用new,也就需要两次delete,但却没有合理的办法让operator*使用者进行那些delete调用。这就会导致资源泄露。

经过上面两种方法都不行,可能你还会想到这种方法:我声明一个static对象不行么?

比如:

 const A& operator* (const A& l, const A& r) {
static A result;
result = .....
return result;
}

看上去完美的解决了这个问题,那么我们这样使用的时候呢?

 bool operator == (const A& l, const A& r);
A a,b,c,d;
if ((a*b) == (c*d)) {
....
}

结果就会出现:(a*b) == (c*d)总是为true,无论a,b,c,d是什么!

将(a*b) == (c*d)拆开来理解,我们就可以知道为什么了。

operator == (operator*(a, b), operator(c*d));

因为到最后位置,都会返回static对象的现值,也就不怪乎为什么返回true了。

◆总结

1.绝不要返回pointer或者referenc指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个local static对象。

最新文章

  1. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理
  2. Ajax_05之跨域请求
  3. codeforce好地方啊 Bear and Elections *
  4. python-基础案例
  5. shell 条件判断参数
  6. java相关各种页面跳转
  7. 阐述 QUEST CENTRAL FOR DB2 八罪
  8. winsock编程WSAEventSelect模型
  9. Java实现GB2312文件转UTF8文件
  10. AOP执行增强-Spring 源码系列(5)
  11. 10.并发包阻塞队列之ArrayBlockingQueue
  12. 爬取知名社区技术文章_pipelines_4
  13. 配置windbg遇到的问题
  14. 1.1专题介绍「深入浅出ASP.NET Core系列」
  15. wb 黑名单批量操作
  16. [No0000197]Windows用户都应该知道的运行命令
  17. Win10系列:JavaScript动画2
  18. TypeScript语言学习笔记(2)
  19. error LNK2001: 无法解析的外部符号 _H5T_NATIVE_DOUBLE_g
  20. java 位运算符,逻辑运算符

热门文章

  1. LeetCode Balanced Binary Tree (判断平衡树)
  2. linux mkfs命令参数及用法详解---linux格式化文件系统命令(包括swap分区)
  3. android Bitmap getByteCount和getRowBytes
  4. json解析之jackson ObjectMapper
  5. MSP430 flash的操作
  6. 打印出从1到最大的n位十进制数
  7. Leetcode OJ : Compare Version Numbers Python solution
  8. NOIP 2015 神奇的幻方
  9. Android--应用开发3(Android layout XML属性)
  10. jQuery遍历多层json数据