什么是左值,什么是右值c++
常见的误区有 = 左边的是左值,右边的是右值。函数
左值:具备存储性质的对象,即lvalue对象,是指要实际占用内存空间、有内存地址的那些实体对象,例如:变量(variables)、函数、函数指针等。性能
右值:相比较于lvalue就是所谓的没有存储性质的对象, 也就是临时对象。spa
在c++中,临时对象不能做为左值,但能够做为常量引用const & 设计
++i = 3; // ok i++ = 3; // error C2106: “=”: 左操做数必须为左值
++i:i先自增1,++i以后仍是指向i的对象
i++:先把i自增以后的值丢给一个临时变量,i++以后指向的是那个临时变量。若是放在单条语句中,这两个没啥区别。指针
int i = 0; // 在这条语句中,i 是左值,0 是临时值,就是右值。 在C++11以前,右值是不能被引用的,如: int &a = 1; // error C2440: “初始化”: 没法从“int”转换为“int &” const int &a = 1;//咱们最多只能用常量引用来绑定一个右值,如: int &&a = 1;//在C++11中,咱们能够引用右值,使用&&来实现:
常量引用能够绑定一个右值,但缺点是这个值不能改变。code
右值引用&&对象
c++中临时对象可能会大量存在,好比string/STL调用中。临时对象中的资源(buffer或者字符串)会随着临时对象的析构而消失,因此通常会在对象析构前把它们(资源)拷贝出来,而不会直接引用这些资源,不然会野指针。blog
其实,既然已是临时对象了,立刻就会被析构掉,因此赶在析构前改一下里面的内容也不会带来太多负面影响,固然是在控制良好的前提下。基于这个思路,咱们能够放心大胆的直接引用临时对象中的资源指针(好比指针赋值,引用该资源),而后把它置空(防止被临时对象释放掉),或者更屌一点的,把咱们意图释放的指针,直接赋值给临时对象的该指针,借助临时对象在析构时会释放它的资源的时机,把咱们想释放的东西给释放掉!内存
多么精妙!
在c11以前,临时对象只能以 const MyClass& my_object 这种方式传递,有const在,因此临时对象是不能被修改的。可是c11引入了右值引用 MyClass&&,致使咱们能够修改临时变量了!
假如你是函数的提供者,你提供了带右值引用的参数,那么,你就大胆的去引用它的资源,修改它的资源吧,不用担忧它还会被使用到,当函数返回以后。由于它是右值引用,该函数的调用者会保证这个参数不会再被使用到。
假如你是函数的调用者,当你发现你有一个左值对象my_object即将再也不被使用到了,就能够用move语义把它转成右值引用丢给函数,任函数去修改它的内容无所谓,由于你肯定它再也不被使用了(若是你肯定不了,那就不能使用move语义)。固然,假如你处理的已是右值了(好比函数返回值),那就跟之前没什么两样。
有了右值引用和转移语义,咱们在设计和实现类时,对于须要动态申请大量资源的类,应该设计转移构造函数和转移赋值函数,以提升应用程序的效率。
(1)参数(右值)的符号必须是右值引用符号,即“&&”。
(2)参数(右值)不能够是常量,由于咱们须要修改右值。
(3)参数(右值)的资源连接和标记必须修改。不然,右值的析构函数就会释放资源。转移到新对象的资源也就无效了。
先记录这么多,等之后有机会再深刻总结。