在 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. Hadoop学习(一) 搭建伪分布式集群

    文章结构 1.准备工作 1.1 配置IP 1.2 关闭防火墙 1.3 修改主机名并与IP绑定 1.4 创建新用户 1.5 配置免密匙 2.安装并配置Hadoop伪分布式集群 2.1 安装Java 2. ...

  2. python之字符串format()方法

    format()方法就是格式化指定的值,然后再将其插入字符串的占位符内 占位符用大括号{}来定义哈,可以使用命名索引{sws}.编号索引{0}.甚至空的占位符{}来标识占位符. 语法就是 string ...

  3. 练习感受以及经验总结(ing)

    connection = DriverManager.getConnection(url, user,password );顺序一定不能搞错,当时顺序写错了.查bug查了一晚上.得益于两个函数都用到了 ...

  4. The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission,iphone手机video标签报错

    The request is not allowed by the user agent or the platform in the current context, possibly becaus ...

  5. ConcurrentModificationException日志关键字报警引发的思考

    本文将记录和分析日志中的ConcurrentModificationException关键字报警,还有一些我的思考,希望对大家有帮助. 一.背景 近期,在日常的日志关键字报警分析时,发现我负责的一个电 ...

  6. 深入 K8s 网络原理(一)- Flannel VXLAN 模式分析

    目录 1. 概述 2. TL;DR 3. Pod 间通信问题的由来 4. 测试环境准备 5. 从 veth 设备聊起 6. 网桥 cni0 6.1 在 Pod 内看网卡信息 6.2 在 host 上看 ...

  7. MySQL运维14-管理及监控工具Mycat-web的安装配置

    一.Mycat-web介绍 Mycat-web(现改名为Mycat-eye)是对Mycat-server提供监控服务,通过JDBC连接对Mycat,MySQL监控,监控远程服务器的cpu,内存,网络, ...

  8. 【Python】【ChatGPT】本地部署ChatGPT学习记录

    学习一下GPT项目的相关使用和部署 一.GPT4ALL模型 Github:https://github.com/nomic-ai/gpt4all GPT4ALL项目部署简易,但是在运行体验上一般,并且 ...

  9. Python——第二章:列表的概念

    在编程中,列表(List)是一种常用的数据结构,用于存储一组有序的元素.列表是Python中的内置数据类型之一,它允许你在一个变量中存储多个值,并且这些值可以是不同的数据类型,包括整数.浮点数.字符串 ...

  10. CentOS7 安装Python3.9以上版本时。编译报错,原因是openssl版本低

    openssl-1.1.1安装 1.前因 python 导入clickhouse_driver需要import ssl和_ssl,报错 File"/home/oracle/python3/l ...