C++移动构造与std::move()

这篇具有很好参考价值的文章主要介绍了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示例。

C++移动构造与std::move()

运行程序会发现,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)) {}

C++移动构造与std::move()文章来源地址https://www.toymoban.com/news/detail-760224.html

需要注意的是

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()的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解和应用C++ std::shared_ptr别名构造函数

    在现代C++中,智能指针是一个极为重要的工具,尤其std::shared_ptr以其自动内存管理、引用计数和多线程安全性等特性深受开发者喜爱。其中一个不太常用但功能强大的构造方式是 别名构造函数 ,它允许我们创建一个共享相同底层对象但是指向其内部不同数据成员或子对象的

    2024年01月16日
    浏览(45)
  • C++ 构造函数实战指南:默认构造、带参数构造、拷贝构造与移动构造

    构造函数是 C++ 中一种特殊的成员函数,当创建类对象时自动调用。它用于初始化对象的状态,例如为属性分配初始值。构造函数与类同名,且没有返回值类型。 C++ 支持多种类型的构造函数,用于满足不同的初始化需求: 默认构造函数: 不带参数的构造函数,通常用于初始化

    2024年04月22日
    浏览(48)
  • C++——移动构造和完美转发

    右值引用是C++11的概念,与之对应的是左值引用。 当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存当中的位置)。 以上的概念是摘录自《C++ primer》。 但是这样的概念并不足以理解。 用一句简单的话描述左值和右值

    2024年02月12日
    浏览(34)
  • 左值引用、右值引用,std::move() 的汇编解释

    1:左值引用 引用其实还是指针,但回避了指针这个名字。由编译器完成从地址中取值。以vs2019反汇编: 如图,指针和引用的汇编代码完全一样。但引用在高级语言层面更友好,对人脑。比如可以少写一个 * 号和 - 。 ,以下是指针和引用的使用: 以上就是左值引用,引用的

    2024年02月04日
    浏览(39)
  • 深入分析C++对象模型之移动构造函数

    接下来我将持续更新“深度解读《深度探索C++对象模型》”系列,敬请期待,欢迎关注!也可以关注公众号:iShare爱分享,自动获得推文和全部的文章列表。 C++11新标准中最重要的特性之一就是引入了支持对象移动的能力,为了支持移动的操作,新标准引入了一种新的引用类

    2024年04月22日
    浏览(48)
  • 【C++】移动构造函数的声明、弃置及重载决议

    本文为观看b站up主happyyang的百草园的视频C++移动构造函数的声明、弃置及重载决议以及查阅cppreference后所做笔记。 Move构造函数的4种状态 隐式声明 (隐式)弃置的移动构造函数。(会弃置合成的移动构造函数和 =default 显式预置的移动构造函数) 需要注意:这个隐式弃置的移

    2024年02月06日
    浏览(32)
  • c++ 移动构造方法为什么要加noexcept

    最近看了候捷老师的c++的教程, 他说移动构造方法要加noexcept,  在vector扩容的时候, 如果有移动构造方法没有加noexcept,是不会调用的. 个人感觉有些神奇, 这就去查下一探究竟. 测试代码如下:  执行结果如下: 我们知道vector 是要扩容的, 在A(A a) 并没有添加noexcept, 所

    2024年02月10日
    浏览(79)
  • 【C++干货铺】C++11新特性——右值引用、移动构造、完美转发

    ========================================================================= 个人主页点击直达:小白不是程序媛 C++系列专栏:C++干货铺 代码仓库:Gitee ========================================================================= 目录 左值与左值引用 右值与右值引用 左值引用和右值引用的比较  左值引用总结:

    2024年01月25日
    浏览(38)
  • <四>move移动语义和forward类型转发

    move : 移动语义,得到右值类型 forward:类型转发,能够识别左值和右值类型 只有两种形式的引用,左值引用和右值引用,万能引用不是一种引用类型,它存在于模板的引用折叠情况,但是能够接受左值和右值 区分左值和右值得一个简单方式就是能不能取地址 一个右值一旦有名字那

    2024年02月02日
    浏览(35)
  • <五>move移动语义和forward类型转发

    move : 移动语义,得到右值类型 forward:类型转发,能够识别左值和右值类型 只有两种形式的引用,左值引用和右值引用,万能引用不是一种引用类型,它存在于模板的引用折叠情况,但是能够接受左值和右值 区分左值和右值得一个简单方式就是能不能取地址 一个右值一旦有名字那

    2024年02月02日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包