简单总结 右值引用 & 转移语义 & 完美转发

右值引用(Rvalue Reference)是C++11的新特性,它实现了 转移语义(move)完美转发(perfect forwarding),主要目的分别是:

  • 减少两个对象交互时不必要的拷贝构造,提升效率
  • 简洁明确定义泛型函数

C++中的变量要么是左值、要么是右值。通俗的左值定义指的是⾮临时变量,⽽右值指的是临时对 象。左值引⽤的符号是⼀个&,右值引⽤是两个&&

绑定到右值的引用,用&&来指定。右值引用只能绑定到要销毁的对象。

int var = 42;
int &l_var = var;
int &&r_var = var; // 错误:不能将右值引⽤绑定到左值上
int &&r_var2 = var + 40; // 正确:将 r_var2 绑定到求和结果上

转移语义

借此可以实现转移语义,即从右值中直接拿数据过来初始化或修改左值, ⽽不需要重新构造一个临时左值后再析构右值。简单来说解决的是各种情形下对象的资源所有权转移的问题。

转移语义可以解决以下问题:

① 用右值参数

// 在实现转移语义之前
MyString a = new MyString(b + "dafs"); // 成功,const &的形参接收了右值参数,但是调用了额外的拷贝构造函数,生成了一个临时变量,销毁临时变量还调用了一次析构函数

// 实现转移语义之后
MyString a = new MyString(b + "dafs"); // 成功,会调用1次移动构造函数

上述提到移动构造函数格式如下:

MyString(MyString && str)
{
   
    _len = str._len; 
    _data = str._data;	// 从右值中获取数据
	str._len = 0;	
	str._data = NULL;	// 销毁右值
}

顺便说一下,C++内置的函数std::move() 可以将一个左值变量转为右值。(后面会详细介绍)

在实现移动构造函数之前,MyString a = move(b) 只会调用拷贝构造函数(如果实现了的话,否则只是复制成员变量)。 而实现了移动构造函数之后,会调用移动构造函数(move(b)被当做右值)。

② 按值返回

在有移动语义之前,当一个函数需要返回一个容器对象时,为了不触发额外的拷贝构造,通常会这样写:

void str_split(const string& s, vector<string>* vec); // 一个按值语义定义的字符串拆分函数

这样vec就必须在外部被定义,很不方便。

而有了移动语义就可以这样:

vector<string> str_split(const string& s) {
   
  vector<string> v;
  // ...
  return v
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值