C++移动构造与std::move()
背景及问题
如下程序所示:
#include<iostream>
class MyString {
public:
MyString() = default;
MyString(const char* data)
{
printf("%s", "MyString Constructed!!\n");
size = strlen(data);
m_data = new char[size];
memcpy(m_data, data, size);
}
~MyString()
{
if (m_data)
{
printf("%s", "MyString Destroyed!!\n");
delete m_data;
}
}
//copy constructor
MyString(const MyString& other) noexcept
{
printf("%s", "MyString Copyed!!\n");
size = other.size;
m_data = new char[size];
memcpy(m_data, other.m_data, size);
}
private:
char* m_data;
int size;
};
class Entity
{
public:
//constructor
Entity(const MyString& string):m_string(string) {}
private:
MyString m_string;
};
int main()
{
Entity entity("Hello");
return 0;
}
程序说明
程序定义了一个MyString类,其中构造函数和拷贝构造函数需要对传进来的字符串开辟空间并复制内容,另外一个Entity类含有一个MyString成员,并在初始化时复制传入的MyString对象。主程序Main中以常量字符串构造一个entity示例。

运行程序会发现,MyString构造了一次,拷贝一次,程序结束析构两次,符合运行逻辑。“Hello”字符串先通过构造函数构造一个临时变量MyString,临时变量再通过Entity内的构造函数拷贝构造给成员变量m_string
问题在于临时变量拷贝构造需要重新开辟空间,并且“用完即扔”,为什么不直接将“hello”构造好的MyString直接“移动”到Entity?这样会节省空间,提高效率。用此引出移动构造和std::move()
移动构造与std::move()
若要实现将临时变量移动到Entity,首先MyString要加入移动构造,如下:
MyString(MyString&& other) noexcept
{
printf("%s", "MyString Moved!!\n");
size = other.size;
m_data = other.m_data;
//clear origin data
other.size = 0;
other.m_data = nullptr;
}
此为移动构造,接受的是一个右值,构造是直接复制原MyString的size与data,不重新开辟空间做深拷贝。并将原MyString清零。接着对Entity构造时使用std::move通知移动构造函数,如下:
Entity(MyString&& string) :m_string(std::move(string)) {}

需要注意的是
1. Entity右值构造时也可不使用std::move,直接将参数强转为右值类型也可以,std::move相当于通知构造函数以移动构造的方式进行
Entity(MyString&& string) :m_string((MyString&&)string) {}
2. 对于形参为Const YourType &类型的既可以接受左值,也可以接受右值。但是使用std::move会编译错误,因为Const值不能被移动,所以Entity构造仍要单独写一个右值构造
3. MyString移动构造时,复制了临时数据的值还要对其清空,因为数据已经被移动,指针没有置空,析构两次会引起Crash问题
C++移动构造与std::move()的更多相关文章
- 移动构造和移动赋值与std::move
------------------------------------移动构造------------------------------------------ 传统的深拷贝深赋值 对于类中,含有 ...
- C++ 11 右值引用以及std::move
转载请注明出处:http://blog.csdn.net/luotuo44/article/details/46779063 新类型: int和int&是什么?都是类型.int是整数类型,in ...
- 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中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...
- item 23: 理解std::move和std::forward
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 根据std::move和std::forward不 ...
- Item 25: 对右值引用使用std::move,对universal引用则使用std::forward
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 右值引用只能绑定那些有资格被move的对象上去.如 ...
- [转载]如何在C++03中模拟C++11的右值引用std::move特性
本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...
- std::move的原理与实现,右值引用的深入理解
这次我真的懂了.... 首先C++11引入了右值引用 && ‘&&’这个要连起来看,是一个整体,C++多了一个关键字而已. 不是引用的引用.是船新的一种语法.那有什么用 ...
- 透彻理解C++11新特性:右值引用、std::move、std::forward
目录 浅拷贝.深拷贝 左值.右值 右值引用类型 强转右值 std::move 重新审视右值引用 右值引用类型和右值的关系 函数参数传递 函数返还值传递 万能引用 引用折叠 完美转发 std::forw ...
随机推荐
- Java判断一个字符串中是否包含数字
知识点 本例考察以下Java知识点: 正则表达式 关于正则表达式: https://www.runoob.com/java/java-regular-expressions.html Characte ...
- CSS加JS实现网页返回顶部功能
最近在设计自己的博客,前端页面在内容很多的时候往下拖动会有滚动条.通常我们都需要一个返回顶部的功能来实现快速来到网页顶部.当然实现方式不止一种,这里我采用的最实用的一种.使用CSS+Jquery方式 ...
- linux和unix中的IO模型总结
高性能网络IO编程模型 一.I/O模型简介 在一个 linux 操作系统中,一般分为用户空间和内核空间. 用户空间一般就是我们进行应用程序编程的地方. 内核空间就是 linux 操作系统自己运行的一些 ...
- MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
描述: 2021-08-xx 13:31:30.049 DEBUG 9208 : ==> Preparing: SELECT SUM(end_vt) - SUM(start_vt) FROM s ...
- 逆向实战31——xhs—xs算法分析
前言 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 公众号链接 目标网站 aH ...
- 名校 AI 课程|斯坦福 CS25:Transformers United 专题讲座
自 2017 年提出后,Transformer 名声大噪,不仅颠覆了自然语言处理(NLP)领域,而且在计算机视觉(CV).强化学习(RL).生成对抗网络(GANs).语音甚至是生物学等领域也大显锋芒, ...
- macOS通过ssh使用PEM登录
在win上面可以使用XSHELL来登录类似于亚马逊这样的安全服务器,在mac上面就可以使用系统自带的命令工具来连接 使用命令 ssh -i key.pem [server] 如下: ssh -i ke ...
- 【Azure 应用服务】Azure Function Python函数中,如何获取Event Hub Trigger的消息Event所属于的PartitionID呢?
问题描述 在通过Azure Function消费Event Hub中的消息时,我们从Function 的 Trigger Details 日志中,可以获得当前Funciton中处理的消息是哪一个分区( ...
- 关于STM32Fx部分引脚不可以正常输出高低电平的解决办法(不可以正常使用)
一.概述 在一次电路版测试中,发现stm32的部分引脚不可以正常的输出高低电平,刚开始以为是板子没有焊接好所以导致的经过多次的测试,发现电路版没问题.当时就想不清楚了,后面就问学长,还有实验室的学长一 ...
- hadoop集群环境搭建--双NameNode
hadoop配置文件修改 个人配置文件压缩包地址: hadoop配置文件压缩包地址点此下载 tar -zxvf 你的压缩包路径/hadoop.tar.gz -C /usr/hadoop(你的hadoo ...