C++ std::move 的一些问题
看 SO 上有一个比较奇怪的问题,
问题代码:
ClassX c = std::move(object_c); // Invokes move constructor ClassX&& cr = std::move(object_c);
ClassX c = cr; // Invokes copy constructor
题主的疑问:cr 是右值了,为什么 `ClassX c = cr` 会触发拷贝构造,而不是移动构造
对此的解释:
If it has a name, it's an lvalue. cr is a name, it's an lvalue.
the code should do ClassX c = std::move(cr);. Keep in mind that std::move does not itself move anything, it only allows a move to occur as-if the variable were an unnamed temporary (such as a return value or result of an expression). It also allows a variable to be bound to an rvalue reference (usually something that is useful for parameter passing). If you find this to be confusing, you are not alone; it is confusing.
我测试的 demo:
#include <iostream>
class A {
public:
A() { std::cout << "Constructors" << std::endl; }
A(const A& a) { std::cout << "Copy Constructors" << std::endl; }
A& operator=(const A& a) {
std::cout << "Assignment Operators" << std::endl;
return *this;
}
A& operator=(const A&& a) {
std::cout << "Move Assignment Operators" << std::endl;
return *this;
}
};
int main() {
A a; // Constructors
A a_5; // Constructors
A a_6; // Constructors
A&& a_1 = std::move(a); // 没有提示
A& a_2 = a; // 没有提示
A a_7 = a_1; // Copy Constructors
A a_3 = a; // Copy Constructors
A a_4(a); // Copy Constructors
A a_8 = std::move(a); // Copy Constructors
a_6 = a_1; // Assignment Operators
a_5 = a; // Assignment Operators
a_1 = a_8; // Assignment Operators
a_6 = std::move(a_1); // Move Assignment Operators
return 0;
}

std::move:
std::move是一个函数模板,用于将一个左值转换为右值引用,从而告诉编译器允许在之后的操作中对该值进行移动语义的操作。- 移动语义是 C++11 引入的特性,它允许在不拷贝的情况下将对象的资源(比如动态分配的内存)转移给其他对象,提高了性能。
std::move并不会真正移动数据,它只是将对象标记为“可以移动”,使得在后续操作中调用移动构造函数或移动赋值运算符。- 使用
std::move的目的是告诉编译器你希望使用移动语义,但要注意,使用之后原来的对象可能处于有效但未定义的状态。
移动构造函数和移动赋值运算符写法如下:
class MyClass {
public:
// 移动构造函数
MyClass(MyClass&& other) {
// 将资源从 other 移动到当前对象
// ...
}
};
class MyClass {
public:
// 移动赋值操作符
MyClass& operator=(MyClass&& other) {
// 将资源从 other 移动到当前对象
// ...
return *this;
}
};
MyClass(MyClass&&) - 移动构造函数:
MyClass(MyClass&&)是一个移动构造函数。它接受一个右值引用作为参数,允许将一个临时对象的资源(如堆上分配的内存)移动到新创建的对象中。- 移动构造函数通常用于在创建新对象时避免不必要的资源拷贝,从而提高性能。例如,在 C++11 中,容器在进行元素插入时可以使用移动构造函数来避免额外的拷贝操作。
- 移动构造函数通常不会修改源对象的状态,而是将源对象的资源所有权转移给新对象。
MyClass& operator=(MyClass&&) - 移动赋值操作符:
MyClass& operator=(MyClass&&)是一个移动赋值操作符。它用于将一个右值引用的对象的资源(如堆上分配的内存)移动到另一个对象中。- 移动赋值操作符用于在赋值操作时避免不必要的资源拷贝,从而提高性能。它可以被用于自定义移动赋值,以实现在赋值时的资源转移。
移动构造函数用于创建新对象并从右值引用中获取资源,而移动赋值操作符用于将资源从一个右值引用的对象移动到另一个对象中
C++ std::move 的一些问题的更多相关文章
- C++ 11中的右值引用以及std::move
看了很多篇文章,现在终于搞懂了C++ 中的右值以及std::move 左值和右值最重要的区别就是右值其实是一个临时的变量 在C++ 11中,也为右值引用增加了新语法,即&& 比 ...
- std::move()和std::forward()
std::move(t)负责将t的类型转换为右值引用,这种功能很有用,可以用在swap中,也可以用来解决完美转发. std::move()的源码如下 template<class _Ty> ...
- C++ 11 右值引用以及std::move
转载请注明出处:http://blog.csdn.net/luotuo44/article/details/46779063 新类型: int和int&是什么?都是类型.int是整数类型,in ...
- std::move()
#include <iostream> #include <utility> #include <vector> #include <string> i ...
- C++11右值引用和std::move语句实例解析
关键字:C++11,右值引用,rvalue,std::move,VS 2015 OS:Windows 10 右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践 ...
- c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用
为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...
- C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward
这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...
- C++11 std::move和std::forward
下文先从C++11引入的几个规则,如引用折叠.右值引用的特殊类型推断规则.static_cast的扩展功能说起,然后通过例子解析std::move和std::forward的推导解析过程,说明std: ...
- item 23: 理解std::move和std::forward
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 根据std::move和std::forward不 ...
- Item 25: 对右值引用使用std::move,对universal引用则使用std::forward
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 右值引用只能绑定那些有资格被move的对象上去.如 ...
随机推荐
- [转帖]LVS入门篇(三)之LVS的工作模式和调度算法
LVS入门篇(三)之LVS的工作模式和调度算法 https://www.cnblogs.com/linuxk/p/9358512.html 1.NAT模型 (1)原理图: ①.客户端(200.10.1 ...
- DBeaver连接国产信创数据库的步骤
DBeaver连接国产信创数据库的步骤 本次连接使用的数据库类型 1.达梦 2.神通 3.人大金仓 4.瀚高 安装DBeaver 通过官网或者是其他网站下载最新的数据库介质 之后的操作为: 这次不感谢 ...
- Springboot 数据库连接池大小简单总结
最近在进行性能压测, 想验证一下产品的极限性能, 在使用openpower 2路22核(SMT4)176线程 512G内存的服务器上面进行性能压测 压测进行到1000并发或者是2000并发时性能有一定 ...
- Python 潮流周刊#22:Python 3.12.0 发布了!!
你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中一则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...
- net core控制台程序使用依赖注入读取appsettings.json配置文件
.net 2.1有用,转自https://www.jianshu.com/p/726d1aa2795c 1.项目下添加appsettings.json文件,并将属性-复制到输出目录,设置为如果较新则复 ...
- 手撕Vuex-实现共享数据
经过上一篇章介绍,完成了添加全局 $store,接下来就是实现共享数据的功能. 在 Vuex 中,共享数据是通过 state 来实现的,所以我们需要在 Nuex.js 文件中实现 state 的功能. ...
- TienChin 活动管理-修改活动接口
前端 activity.js 直接替换现有的,最求速度了,后面在详细一个个记录,不在过多解释了. import request from '@/utils/request' /** * 查询活动列表 ...
- 做知识图谱遇到的环境问题合集【spacy、gensim、keras_contrib等】
1.python:spacy.gensim库的安装遇到问题及bug处理 见: python:spacy.gensim库的安装遇到问题及bug处理_汀.的博客-CSDN博客1.spacySpaCy最新版 ...
- 9.3 Windows驱动开发:内核解析PE结构节表
在笔者上一篇文章<内核解析PE结构导出表>介绍了如何解析内存导出表结构,本章将继续延申实现解析PE结构的PE头,PE节表等数据,总体而言内核中解析PE结构与应用层没什么不同,在上一篇文章中 ...
- 19.10 Boost Asio 同步文件传输
在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含goodbye lyshark关键词来验证文件是否传输结束了,当然了这种传输方式明 ...