返回值优化问题

近来看到小李子写了篇blog,题目为返回值优化。

文章如下。

return Integer(left.i+right.i); //创建一个临时对象并返回他,不会调用析构函数,效率高。
Interger tmp(left.i+right.i);
return tmp;              //创建了局部对象,有析构函数。

————————————————————————————————

这里感觉有些诡异。

于是编写了简单的程序

  1. // TempClassDestroy.cpp : Defines the entry point for the console application.
  2. //
    1. #include “stdafx.h”
  3. #include 
  4. using namespace std;
  5. class A
  6. {
  7. private :
  8. int a;
  9. public :
  10. A( int a)
  11. {
  12. this ->a = a;
  13. }
  14. ~A()
  15. {
  16. cout << “AA:” <<a<<endl;
  17. }
  18. };
      1. A& foo1( int c)
  19. {
  20. return A©;
  21. }
      1. A foo2( int c)
  22. {
  23. return A©;
  24. }
    1. A foo3( int c)
  25. {
  26. A a©;
  27. return a;
  28. }
  29. A& foo4( int c)
  30. {
  31. A a©;
  32. return a;
  33. }
  34. int _tmain( int argc, _TCHAR* argv[])
  35. {
  36. foo1(1);
  37. cout << “foo1” <<endl;
  38. foo2(2);
  39. cout << “foo2” <<endl;
  40. foo3(3);
  41. cout << “foo3” <<endl;
  42. foo4(4);
  43. cout << “foo4” <<endl;
        1. A& a = foo1(1);
  44. A& b = foo2(2);
  45. A& c = foo3(3);
  46. A& d = foo4(4);
  47. return 0;
  48. }
    1. 最后的运行结果是:

AA:1
foo1
AA:2
foo2
AA:3
AA:3
foo3
AA:4
foo4
AA:1
AA:3
AA:4
AA:3
AA:2

当然前面的内容:

AA:1
foo1
AA:2
foo2
AA:3
AA:3
foo3
AA:4
foo4

第二个函数与第三个函数可以很明显的看到效率的差异。因为foo3函数中析构函数出现了两次。

(这里第一和第四个函数有明显错误,可以根据后面的测试程序看出)

但是第一个函数也恰恰说明 return Integer(left.i+right.i); //创建一个临时对象并返回他,不会调用析构函数,效率高。
这句话有些问题。因为在调试的时候可以看出有调用析构函数。并且结果

AA:1
AA:3
AA:4
AA:3
AA:2

也能说明问题。

由于第一个函数和第四个函数产生的效果一样。

所以我提出一个可能的假设:

return Integer(left.i+right.i);
只有当返回值为Integer,而非Integer&才能有创建一个临时对象并返回他,不会调用析构函数。

当然因为程序的正确性要求,我们不可能编写类似于foo1的函数。