浅析C++11右值引用和move语义

本文简明扼要地介绍了C++11中右值引用的概念及其重要性,阐述了左值与右值的区别,以及如何通过move语义实现资源的有效转移,展示了如何利用std::move进行对象的移动而非复制,从而提高程序效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  右值引用是C++11中新引入的概念,该方法是为了支持移动而引入的额一个新的引用类型。本文将以最简洁的描述来介绍右值引用和move语义的基本概念。我们通常见到的引用(int &a=b;)可以称之为左值引用,而右值引用则是int &&a的形式。右值引用的一个重要性质和作用就是只能绑定到一个将要销毁的对象,因此我们可以将右值引用的资源移动到另一个对象中,下面将具体解释其含义辑器使用。

0x01 左值和右值的概念

在编程语言中我们将变量和对象分为左值和右值,下面举例介绍。

  • 左值:既可以放在等号左侧,也可以放在等号右侧的变量。例如下面的例子:
int a = 1;
int& b = a

上面的变量a既可以放在等号的左侧也可以放在等号的右侧,所以她是左值。

  • 右值:只可以放在等号右侧的变量。例如下面的例子:
int a = 1;
int b = a + 2;
int& c = a + 2; //error
a+2 = 3; // error

这里的a+2只能放在等好的右侧,所以a+2是右值。
  为什么a+2只能放在等号右侧呢?原因在于a+2会产生一个临时变量,b=a+2实际上是先算出a+2的结果存储到临时变量然后赋值给b,并销毁这个临时变量。如果将a+2放到等好的左侧,那么将产生无意义的结果。

  综合上面的左值和右值的概念我们可以得到“左值持久,右值短暂”的概念。左值持久存在,右值将在运算结束后销毁。

0x02 右值引用

  上面已经介绍了右值的概念,从右值引用的名字上可以看出,右值引用就是对右值进行引用操作。例子如下:

int a = 1;
//int& b = a + 2; //error
int&& b = a + 2;

  我们使用两个与符号表示右值引用,从上面的例子中可以看出,普通的引用的等号右侧不可以是一个右值,而右值引用的左侧必须是一个右值。那么中间道理发生了什么呢?其实右值引用指向的是将要销毁的对象,也就是前面提到的a+2产出的临时对象,在对象销毁之前该引用可以接管其资源。

  有些时候我们偏偏需要将左值转换为右值引用怎么办呢?ok move语义登场。

0x03 move语义

  从上面的介绍我们可以总结出,只有右值可以绑定到右值引用上。但是,话不能说的太满。我们总有办法能将左值也绑定到右值引用上,我们可以显式的使用move将一个左值转换为对用的右值引用类型。如下:

int a = 1;
int&& b = std::move(a);

此时,a和b的地址是相同的,b将是a的应用。

  总结出来move的概念其实很简单,就一句话:将一个左值转换为对用的右值引用类型。

  这里需要注意一点的就是,右值引用的是将要销毁的对象,使用move调用意味着告诉编译器我们有一个左值,但想像右值一样使用,所以调用move后原来的对象除了赋值和销毁它外不能有其他的操作。


C++11 move例程:
#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;
    //调用常规的拷贝构造函数,新建字符数组,拷贝数据
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";
    //调用移动构造函数,掏空str,掏空后,最好不要使用str
    v.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";
    std::cout << "The contents of the vector are \"" << v[0]
                                         << "\", \"" << v[1] << "\"\n";
}

在这里插入图片描述
可以看到,std::move()就是将左值转换为对应的右值引用类型,且调用后销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值