在 C++11 之前,值类型变量的传递会导致把它完整的拷贝一份

比如说把一个 vector 作为函数返回值赋值给某个局部变量,他就会调用 vector 的拷贝构造函数创建一个完整的副本,把这个副本作为函数返回的临时变量,然后把这个临时变量赋值给那个局部变量时又会再次拷贝构造

(不过这其实会被大多数编译器优化掉)

右值

上面例子中的临时变量就是一个右值

右值是无法获取到地址的值

大概可以理解为临时的变量或者没有被声明但是实际存在的变量

函数的返回值,还有常量都是右值

右值引用

根据名字我们知道它是一个右值的引用(废话)

使用右值引用接收右值可以让右值不被销毁,同时也不会拷贝任何数据

举个例子,下面代码中 str 变量接收了 GetStr 函数返回的右值

string GetStr() {
return "Hello world";
} int main() {
string&& str = GetStr();
return 0;
}

转移构造函数

因为右值被使用过后就会被销毁,所以完整拷贝它的备份是很不划算的

我们希望把右值里的数据直接偷出来

那么我们可以通过转移构造函数来实现

class Array {
private:
int* arr;
int len; public:
Array(int len) : arr(new int[len]) {}
~Array() {
if (arr) delete[] arr;
}
Array(const Array& other) : len(other.len) {
// 拷贝构造会导致整个数组被复制
arr = new int[other.len];
memcpy(arr, other.arr, len * sizeof(int));
}
Array(Array&& other) : arr(other.arr) {
// 转移构造可以直接把数组的指针偷过来
other.arr = NULL;
}
};

可以看到上面的代码把 other 这个右值里的 arr 偷走了

另外类似的还有转移赋值函数,也是使用右值引用传参,然后在函数里把右值里的东西偷出来

转移语义

那么又有一个问题,如果有一个左值,他以后不会再被用到,我希望能把它里面的东西偷出来放到另一个左值里,怎么实现

使用 std::move,把一个左值转换为右值,然后把它里面存的东西搬空

看这个例子就很清晰了

class Array {
private:
int* arr;
int len; public:
Array(int len) : arr(new int[len]) {}
~Array() {
if (arr) delete[] arr;
}
Array(const Array& other) : len(other.len) {
// 拷贝构造会导致整个数组被复制
arr = new int[other.len];
memcpy(arr, other.arr, len * sizeof(int));
}
Array(Array&& other) : arr(other.arr) {
// 转移构造可以直接把数组的指针偷过来
other.arr = NULL;
}
}; int main() {
Array a(100);
Array b(move(a));
return 0;
}

可以看到变量 a 里存的数组指针被变量 b 偷出来了,从而避免了整个数组的拷贝

C++右值引用与转移语义简要介绍的更多相关文章

  1. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  2. C++11 标准新特性: 右值引用与转移语义

    文章出处:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) ...

  3. C++11 右值引用和转移语义

    新特性的目的 右值引用 (Rvalue Referene) 是 C++ 新标准 (C++11, 11 代表 2011 年 ) 中引入的新特性 , 它实现了转移语义 (Move Sementics) 和 ...

  4. C++11 右值引用 与 转移语义

    新特性的目的 右值引用(R-value Reference)是C++新标准(C++11, 11代表2011年)中引入的新特性,它实现了转移语义(Move Semantics)和精确传递(Perfect ...

  5. C++右值引用与转移语义

    std::forwad? C++11 中定义的 T&& 的推导规则为: 右值实参为右值引用,左值实参仍然为左值引用. 参考: 右值引用与转移语义

  6. 右值引用与转移语义(C++11)

    参考资料: http://www.cnblogs.com/lebronjames/p/3614773.html 左值和右值定义: C++( 包括 C) 中所有的表达式和变量要么是左值,要么是右值.通俗 ...

  7. C++11新特性:右值引用和转移构造函数

    问题背景 #include <iostream> using namespace std; vector<int> doubleValues (const vector< ...

  8. C++11新特性之右值引用(&&)、移动语义(move)、完美转换(forward)

    1. 右值引用 个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能. 比如下面的代码: String Fun() { String str = "hello world"; ...

  9. [c++11]右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  10. [转][c++11]我理解的右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

随机推荐

  1. Ubuntu 20.04 查看显示器信息

    安装 ddcutil apt install ddcutil 输入命令 ddcutil detect --verbose 输出类似如下: Output level: Verbose Reporting ...

  2. LabVIEW基于机器视觉的实验室设备管理系统(1)

    目录 MySQL数据库 建表 表格转换格式 导入数据库 效果演示 今天,我们就来把慢蜗牛在大二时期做的大创来复现一遍.后续会逐渐更新,带着大家一步一步做出属于自己的管理系统. MySQL数据库 在开始 ...

  3. 2021年前端面试题——JS

    目录: DOM事件流有那些阶段? 解释事件冒泡以及如何阻止它? 事件委派/事件委托是什么? 如何理解 JS 中的this关键字? 更改this指向的方法有那些? apply.call.bind 区别? ...

  4. 【Android】学习day05|RadioButton

    注意事项:当使用默认选中标签:check时,必须要给标签加id,否则失效. 这个没什么,挺简单的,就记录一下代码[监听事件] package com.example.app02; import and ...

  5. [ABC313F] Flip Machines

    Problem Statement There are $N$ cards numbered $1$ through $N$. Each face of a card has an integer w ...

  6. Java 21 虚拟线程:使用指南(一)

    虚拟线程是由 Java 21 版本中实现的一种轻量级线程.它由 JVM 进行创建以及管理.虚拟线程和传统线程(我们称之为平台线程)之间的主要区别在于,我们可以轻松地在一个 Java 程序中运行大量.甚 ...

  7. ElasticSearch之cat indices API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/indices?v=true&pretty" --cacert $ES_H ...

  8. vivo 海量微服务架构最新实践

    作者:来自 vivo 互联网中间件团队 本文根据罗亮老师在"2023 vivo开发者大会"现场演讲内容整理而成.公众号回复[2023 VDC]获取互联网技术分会场议题相关资料. v ...

  9. DevExpress源码编译(部分翻译)

    环境准备(DevExpress v18.2 ~22.2): vs2015至2022版本 .net framework 4.7.2或更高(实际我们项目用4.5.2可以编译,并不是所有的工程都需要高版本) ...

  10. 第七部分_Shell脚本之循环

    for循环语句 关键词:爱的魔力转圈圈 1. for循环语法结构 空行相对于for循环类似于空格 ㈠ 列表循环 列表for循环:用于将一组命令执行已知的次数 基本语法格式 for variable i ...