孤独的猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

右值引用就是对一个右值进行引用的类型。因为右值不具名,所以我们只能通过引用的方式找到它

无论声明左值引用还是右值引用都必须立即进行初始化,因为引用类型本身并不具有所绑定对象的内存,只是该对象的一个别名。
看一下下面的代码

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int g_constructCount = 0;
 5 int g_copyConstructCount = 0;
 6 int g_destructCount = 0;
 7 struct A
 8 {
 9     A() {
10         cout << "construct: " << ++g_constructCount << endl;
11     }
12 
13     A(const A& a)
14     {
15         cout << "copy construct: " << ++g_copyConstructCount <<         endl;
16     }
17 
18     ~A()
19     {
20         cout << "destruct: " << ++g_destructCount << endl;
21     }
22 };
23 
24 A GetA()
25 {
26     return A();
27 }
28 
29 int main()
30 {
31     A a = GetA();
32     return 0;
33 }

如果在g++下编译时设置编译选项-fno-elide-constructors,则会得到如下的结果

 从上面的例子可以看到,在没有返回值优化的情况下,拷贝构造函数调用了两次,一次是GetA()函数内部创建的临时对象,另一次是构造a对象产生的。

为了清楚地观察临时值,g++ test.c -o test.out,运行test.out得到结果

这是编译器默认优化的效果,但这不是C++标准,是各编译器的优化规则。如果我们修改int main为

int main()

{

  A&& a=GetA();

  return 0;

}

输出结果为

 通过右值引用,比之前少了一次拷贝构造和一次析构,原因在于右值引用绑定了右值,让临时右值的生命周期延长了。

 

 

 

posted on 2021-10-14 14:47  孤独的猫  阅读(72)  评论(0编辑  收藏  举报