码迷,mamicode.com
首页 > 编程语言 > 详细

C++ 11中的右值引用

时间:2020-10-26 11:50:50      阅读:24      评论:0      收藏:0      [点我收藏+]

标签:它的   回忆   而不是   get   临时   引用传递   等价   对象   了解   

C++ 11中的右值引用

左值引用

C++中,有一个C语言没有的概念叫做引用,也就是

int i = 10;
int& j = i;

所谓引用,可以理解成指针常量,及它的指向无法更改,在初始化时便被确定下来,但可以修改地址中的内容。指针与引用还是有差别的,但本文不予以说明,具体可以参考百度

const int* p1 = &a;		//常量指针,p1与p2等价,个人偏爱p1
int const* p2 = &b;		//常量指针
int *const p3 = &c;		//指针常量,引用

右值引用

int&& i = 10;

此即为右值引用,绑定了纯右值10,而非为引用的引用。右值引用在C++ 11中被加入,主要是为了解决两个问题

  1. 临时对象的非必要的拷贝操作
  2. 模板函数中的非完美转发

首先在C++ 11后,值分为左值,将亡值与纯右值三种。像是非引用的返回值,lambda表达式等等都属于纯右值,纯右值在表达式结束后将会被销毁。而std::move中的参数(或是将要被移动的对象)与返回值等,都属于将亡值

临时对象

临时对象便是上文所说到的纯右值了。不可见的匿名对象(不出现在我们的源码当中)的临时对象通常出现在以下两种情况

  1. 传递函数参数时发生的隐式转换
  2. 函数返回对象时
第一种
int GetLength(const std::string& str);
char c[];
//调用上面的函数
std::cout << GetLength(c) << std::endl;

应该一眼就能看出,在将c传入GetLength函数中时发生了一次隐式转换。具体的来说,编译器会生产出一个std::string的临时变量(暂且称作s1),然后调用s1的构造函数,以c为参数进行构造,然后再将s1作为函数参数传入GetLength中。也就是说GetLength中的str将绑定在这个临时变量s1上,直到函数返回时销毁。这种转换只会出现在函数参数以值传递或以常量引用(reference - to - const)传递上

int GetLength(std::string str);
int GetLength(const std::string& str);

那么为什么必须是reference - to - const而不是reference - to - non - const呢

int GetLength(std::string& str);
char c[];
//std::cout << GetLength(c) << std::endl;	//编译器报错,非const引用传递参数不能完成隐式转化

回忆一下值传递和引用传递,后者是可以在函数体内更改原对象的值的。对于隐式转换来说,参数str将会绑定在一个临时变量上,而我们在函数中做出的修改是在这个临时变量上的,与原对象没有任何关系,像是一头替罪羊。这就是C++中禁止reference - to - non - const参数产生临时变量的原因

第二种

待更新

C++ 11中的右值引用

标签:它的   回忆   而不是   get   临时   引用传递   等价   对象   了解   

原文地址:https://www.cnblogs.com/tuapu/p/13876150.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!