先贴一段代码(在vs2015编译通过):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <utility>
class Item {
public:
char name;
int val;
public:
~Item(){
printf("[dtor called] (%c, %i) \n", name, val);
}
Item():name('_'), val(0) {
printf("[default ctor called] \n");
}
Item(char n, int v):name(n), val(v) {
printf("[ctor called] (%c, %i) \n", name, val);
}
Item(const Item& a) {
printf("[copy ctor called] (%c, %i) -> (%c, %i)\n", a.name, a.val, name, val);
name = a.name;
val = a.val;
}
Item& operator = (const Item& a)
{
printf("[operator = called] (%c, %i) -> (%c, %i)\n", a.name, a.val, name, val);
name = a.name;
val = a.val;
return *this;
}
Item& operator = (Item&& a)
{
printf("[move operator = called] (%c, %i) -> (%c, %i)\n", a.name, a.val, name, val);
name = a.name;
val = a.val;
return *this;
}
};
Item test1(void)
{
return Item('a', 1);
}
Item test2(void)
{
Item a('b',2);
return a;
}
Item&& test3(void)
{
Item a('c', 3);
return std::move(a);
}
Item test4(void)
{
Item a('d', 4);
return std::move(a);
}
Item test5(void)
{
Item&& e = Item('e', 5);
return e;
}
int main() {
printf("----------Item a = test1() --------------\n");
Item a = test1();
printf("----------Item&& b = test2() --------------\n");
Item&& b = test2();
printf("----------Item&& c = test3() --------------\n");
Item&& c = test3();
printf("----------Item&& d = test4() --------------\n");
Item&& d = test4();
printf("--------- Item&& e = test5() --------------\n");
Item&& e = test5();
printf("\n---------- test end --------------\n\n");
return 0;
}
Debug运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
----------Item a = test1() --------------
[ctor called] (a, 1)
----------Item&& b = test2() --------------
[ctor called] (b, 2)
[copy ctor called] (b, 2) -> (? -858993460)
[dtor called] (b, 2)
----------Item&& c = test3() --------------
[ctor called] (c, 3)
[dtor called] (c, 3)
----------Item&& d = test4() --------------
[ctor called] (d, 4)
[copy ctor called] (d, 4) -> (? -858993460)
[dtor called] (d, 4)
--------- Item&& e = test5() --------------
[ctor called] (e, 5)
[copy ctor called] (e, 5) -> (? -858993460)
[dtor called] (e, 5)
---------- test end --------------
[dtor called] (e, 5)
[dtor called] (d, 4)
[dtor called] (b, 2)
[dtor called] (a, 1)
从结果可以总结出:
- test1函数才是最正确的写法,胡乱使用&&符号反而多调用了几次函数。
- 对比test2、test1会发现,如果要返回一个函数临时变量,最好写成匿名变量的形式(test1),这样的写法编译器才能够做返回值优化。
- 其中test3的写法是错误的,看test3的打印以及test end之后的输出可以发现,变量c并没有被成功取到函数之外,c在test3返回时就被析构了。
- test2、test4、test5几乎是一样的(根据打印来看的话),但test2是三者中最简洁的写法。
Release运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
----------Item a = test1() --------------
[ctor called] (a, 1)
----------Item&& b = test2() --------------
[ctor called] (b, 2)
----------Item&& c = test3() --------------
[ctor called] (c, 3)
[dtor called] (c, 3)
----------Item&& d = test4() --------------
[ctor called] (d, 4)
[copy ctor called] (d, 4) -> (<, 3805970)
[dtor called] (d, 4)
--------- Item&& e = test5() --------------
[ctor called] (e, 5)
[copy ctor called] (e, 5) -> (? 1)
[dtor called] (e, 5)
---------- test end --------------
[dtor called] (e, 5)
[dtor called] (d, 4)
[dtor called] (b, 2)
[dtor called] (a, 1)
对比Debug版的输出,会发现test2函数被编译优化成test1了。
当然,还是尽量把代码写成test1的写法吧。简洁得多。
(未经授权禁止转载)
Written on October 30, 2015
写作不易,您的支持是我写作的动力!