在 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. Git、GitHub、Gitlab的区别以及与SVN的比较

    概念解析 Git   Git是一个开源的分布式版本控制系统(Version Control System,VCS),可以有效.高速地处理项目版本管理.   版本控制是一种记录一个或若干文件内容变化,以 ...

  2. 阿里云轻量服务器上编译安装docker trojan时报错 fatal error: Killed signal terminated program cc1plus compilation

    轻量服务器编译安装docker trojan时报错   72%时 通过以下操作解决,和编译其他软件类似,是内存不足引起的 编译安装swoole的时候报错 fatal error: Killed sig ...

  3. super学习

    2022-10-02 16:27:38 super super代表的是"当前对象(this)"的父类型特征 概念 1.super是一个关键字,全部小写. 2.super和this对 ...

  4. java集合框架(三)ArrayList常见方法的使用

    @[toc]## 一.什么是ArrarListArrayList是Java中的一个动态数组类,可以根据实际需要自动调整数组的大小.ArrayList是基于数组实现的,它内部维护的是一个Object数组 ...

  5. RTMP协议学习——Message与Chunk解读

    前言 之前通过对抓包数据的学习和分析,对RTMP协议有了一个整体的认知,大致了解了RTMP从建立连接到播放视频的流程,文章请看<RTMP协议学习--从握手到播放>.但是对于RTMP消息传输 ...

  6. jdk21的外部函数和内存API(MemorySegment)(官方翻译)

    1.jdk21:   引入一个 API,通过该 API,Java 程序可以与 Java 运行时之外的代码和数据进行互操作.通过有效地调用外部函数(即JVM外部的代码)和安全地访问外部内存(即不由JVM ...

  7. [NOI online2022提高B] 讨论

    题目描述 有 \(n\) 个人正在打模拟赛,模拟赛有 \(n\) 道题目. 有两人都会的题目并且没有人会的题目包含另一个人时,两者之间才会讨论. (定义第 ii 个人会的题目的集合为 \(S_i\) ...

  8. CICD实践1:环境安装篇

    一.CICD技术选型 配置管理工具 工具 需求管理工具 使用禅道 代码管理工具 使用Gitlab 编译构建工具 搭建Jenkins,使用Jenkinsfile 制品库工具 nexus 文档管理工具 C ...

  9. LeetCode15:三数之和(双指针)

     解题思路:常规解法很容易想到O(n^3)的解法,但是,n最大为1000,很显然会超时. 如何优化到O(n^2),a+b+c =0,我们只需要判断 a+b的相反数是否在数组中出现,而且元素的取值范围在 ...

  10. 牛客小白月赛2 E题 是是非非 (尼姆博弈)

    题目链接:https://www.nowcoder.com/acm/contest/86/E 解题思路:由尼姆博弈我们可以知道,如果所有堆的石子数量异或为0,那么先手必败,否则先手必胜. 由异或我们可 ...