【c++11】移动构造的性质 和 与拷贝构造的比较(详解)

news2024/11/25 20:55:53

文章目录

  • 定义
  • 性质
    • 移动构造的定义
    • 实例代码分析
    • 移动构造 与 拷贝构造的比较
    • 移动赋值 和 拷贝赋值
  • 应用场景

定义

移动构造(Move Constructor)是一种特殊的构造函数,它通过接收一个右值引用参数来创建新对象,并从传入的对象中“移动”资源而不是执行深拷贝。

移动构造的使用场景:

  • 在函数中返回临时对象时,可以通过移动构造函数避免不必要的拷贝操作。

  • 在容器中插入临时对象时,可以通过移动构造函数实现高效插入和删除操作。

  • 在进行资源管理时,通过移动构造函数可以从一个对象转移资源所有权,提高性能。


性质

移动构造本质是将参数右值的资源窃取过来,占位已有,那么就不 用做深拷贝了,所以它叫做移动构造,就是窃取别人的资源来构造自己。

移动构造的定义

由于移动构造函数的参数为右值引用参数,所以遵循下面的写法:

class MyClass {
public:
    // 移动构造函数
    MyClass(MyClass&& other) {
        // 资源的转移或交换操作
        // ...
    }
};

实例代码分析

下面的代码 是自定义的string 类,省略了部分功能/代码,用来作分析:

namespace aiyimu
{
	class string
	{
	public:
		// 构造函数
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		void swap(string& s)
		{
			::swap(_str, s._str); //std::swap -> ::swap
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}

		// 拷贝构造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) <---> 拷贝构造(深拷贝)" << endl;
			// 拷贝操作
			_str = new char[s._capacity + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;
		}

		// 移动构造
		// 以右值引用作参数
		string(string&& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) <---> 资源转移" << endl;
			swap(s);
		}
		
		// 拷贝赋值运算符
		string& operator=(const string& s)
		{
			cout << "string& operator=(string s) <---> 拷贝赋值(深拷贝)" << endl;
			string tmp(s);
			swap(tmp);

			return *this;
		}

		// 移动赋值运算符
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) <---> 移动赋值(资源移动)" << endl;
			swap(s);

			return *this;
		}		

		// 析构
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}

	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}

这里分别实现了 拷贝构造 string(const string& s) 和 移动构造 string(string&& s),下面将举例一些 适用移动构造 的情况。


移动构造 与 拷贝构造的比较

对上面定义的string类,用下面的代码进行比较:

  • 由于我们实现的 拷贝构造 的参数是const 类型,所以既可以进行左值引用也可以进行右值引用
  • 当存在移动构造时,传入右值优先调用移动构造,否则构造此时的拷贝构造。
  • 对下面的代码,to_string 的 参数是10(右值),调用移动构造,但我们讲两种构造都作讨论。
    在这里插入图片描述

在这里插入图片描述


移动赋值 和 拷贝赋值

移动赋值(Move Assignment)是一种在编程语言中用于将一个对象的资源(如内存空间)转移到另一个对象的操作。

// 移动赋值
string& operator=(string&& s)
{
	cout << "string& operator=(string&& s) <---> 移动赋值(资源移动)" << endl;
	swap(s);

	return *this;
}

通常情况下,对象的赋值操作会将源对象的值复制到目标对象中,但是在某些情况下,复制操作可能是低效或不可行的,或者我们希望避免不必要的资源拷贝。这时,移动赋值就可以派上用场。

int main()
{
	aiyimu::string ret("114");
	ret = to_string(514);
	return 0;
}

对于上述代码,当执行的是拷贝构造+拷贝赋值时:

在这里插入图片描述

可以看出拷贝构造时 进行了两次深拷贝

而当执行的是移动构造+移动赋值时:

在这里插入图片描述

此时仅有一次资源移动

应用场景

  1. 对于临时对象:当有一个临时对象(右值),并且希望将其资源转移给其他对象,而不进行深拷贝时,可以使用移动构造。移动构造会以低开销地将资源从临时对象转移到目标对象,避免了不必要的资源拷贝

  2. 对于大型对象:如果对象比较大且复制操作开销较大,那么使用移动构造可以提高性能。通过移动构造,可以避免进行昂贵的深拷贝,而仅仅是移动指针或资源所有权,从而更高效地创建新对象

  3. 对于资源管理类:当你编写需要管理底层资源(如内存、文件句柄等)的类时,移动构造可以实现资源的转移和所有权的转移。例如,当一个对象被赋值给另一个对象时,可以通过移动构造将资源从源对象转移到目标对象,同时确保源对象在析构时不会释放资源。

  4. 对于容器类:在使用容器类(如向量、列表等)时,如果需要在容器之间转移元素而不是进行深拷贝,可以使用移动构造。这可以减少元素的拷贝数量,并提高插入、删除等操作的性能。

即:移动构造适用于需要转移资源所有权、避免不必要的拷贝、提高性能或实现资源管理的情况下。它通常用于处理临时对象、大型对象和涉及资源管理的类和容器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统——Windows 线程的互斥与同步

一、实验题目 Windows 线程的互斥与同步 二、实验目的 (1) 回顾操作系统进程、线程的有关概念&#xff0c;加深对 Windows 线程的理解。 (2) 了解互斥体对象&#xff0c;利用互斥与同步操作编写生产者-消费者问题的并发程序&#xff0c;加深对 P (即 semWait)、V(即 semSig…

[Spec] WiFi P2P Discovery

学习资料&#xff1a;Android Miracast 投屏 目录 学习资料&#xff1a;Android Miracast 投屏 P2P discovery Introduction Device Discovery procedures Listen State Search State Scan Phase Find Phase 总结 P2P discovery Introduction P2P发现使P2P设备能够快速…

WiSA Technologies开始接受WiSA E多声道音频开发套件的预订

美国俄勒冈州比弗顿市 — 2023年6月13日 — 为智能设备和下一代家庭娱乐系统提供沉浸式无线声效技术的领先供应商WiSA Technologies股份有限公司&#xff08;NASDAQ股票代码&#xff1a;WISA&#xff09;宣布&#xff1a;该公司现在正在接受其WiSA E开发套件的预订。WiSA E使用…

论文不详细解读(一)——MoCo系列

1. MoCo v1 论文名称&#xff1a; Momentum Contrast for Unsupervised Visual Representation Learning 开源地址&#xff1a;https://github.com/facebookresearch/moco 大佬详细解读&#xff1a;https://zhuanlan.zhihu.com/p/382763210 motivation 原始的端到端自监督方…

听说软件测试岗位基本都是女孩子在做?

“听我一朋友说&#xff0c;测试岗位基本都是女孩子做。” 不知道是不是以前“软件测试岗”给人印象是“不需要太多技术含量”的错觉&#xff0c;从而大部分外行认为从业软件测试的人员中女生应占了大多数。比如有人就觉得&#xff1a;软件测试主要是细心活&#xff0c;所以女生…

Python多任务执行方式

一、多任务的执行方式 并发&#xff1a;在一段时间内交替去执行任务&#xff08;单核CPU&#xff09;并行&#xff1a;CPU核数大于任务数 二、进程&#xff08;实现多任务&#xff09;——操作系统调度 进程是操作系统进行资源分配的基本单元一个程序至少有一个进程&#xf…

极致呈现系列之:EchartsK线图的数据量化

目录 什么是K线图K线图的特性及应用场景K线图的特性K线图的应用场景 Echarts中K线图的常用属性Vue3中创建K线图 什么是K线图 K线图是一种用于展示金融市场中股票、期货、外汇等交易品种价格走势的图表形式。它由一根根的垂直线条和水平线组成&#xff0c;能够直观地显示出一段…

OJ #378 字符串括号匹配2

题目描述 ​ 给出一个字符串&#xff0c;判断其中的左右括号是否匹配。 ​ 注&#xff1a;需同时判断左右圆括号 ( 和 ) &#xff0c;左右中括号 [和]&#xff0c;左右大括号 {和}。 ​ 不需要考虑括号之间的优先级的问题&#xff0c;也就是说&#xff0c;小括号包含大括号&…

NodeJS应届毕业生财务管理系统-计算机毕设 附源码82886

基于VueNodeJS应届毕业生财务管理系统 摘 要 随着互联网大趋势的到来&#xff0c;社会的方方面面&#xff0c;各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去&#xff0c;而其中最好的方式就是建立网络管理系统&#xff0c;并对其进行信息管理。由于现在…

合宙Air724UG Cat.1模块硬件设计指南--看门狗

概述 Air724UG 内部已经自带了看门狗&#xff0c;4秒进行一次喂狗&#xff0c;如果主芯片异常死机&#xff0c;自带的看门狗15秒左右会硬件复位主芯片。 另外主芯片死机情况下&#xff0c;reset键也可以硬重启。 通常情况下不需要外加硬件看门狗&#xff0c;如果对系统稳定性有…

FreeRTOS和uC/OS:选择入手哪个RTOS更合适?

FreeRTOS和uC/OS是两个流行的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;用于嵌入式系统开发。它们有一些区别&#xff0c;但选择哪个先入手取决于你的需求和项目要求。 复杂度&#xff1a;FreeRTOS是一个相对较简单的RTOS&#xff0c;它专注于提供基本的实时调度和…

西门子Mendix 入门 3

导航页面&#xff1a;用于在应用程序中添加或修改其他页面 创建查看查看和添加公司不同部门的页面 打开导航页面&#xff0c;添加新项目 选择TaskTracke新建一个名为Department_Overview的页面&#xff0c;并选择List作为模板 创建成功 现在转到 Department_Overview页面 链接数…

揭秘2023年项目管理软件排行榜实力榜

在现代的商业世界中&#xff0c;项目管理是必不可少的一个组成部分。为了成功地管理一个项目&#xff0c;项目经理需要实施一种系统化的方法来确保项目在时间和预算的约束下成功。这就需要使用专业的项目管理软件。因此&#xff0c;项目管理软件在商业领域中扮演着至关重要的角…

管理类联考——逻辑——知识篇——分析推理——一、排序——haimian

排序 题型特征 排序题通常是依据大小、时间、名次和前后等条件将几个元素有序地排在若干连续排列的位置上。解题时要找出一个对整个排列起决定作用的条件&#xff0c;然后涉及先后位置的条件尽可能结合起来进行解题。 思维导图 思路点拨 注意选项的模式&#xff0c;如果已经…

阿维塔进攻全场景NCA:“遥遥领先”能否赢得市场买单?

阿维塔正在高阶智驾的落地上奋力探索。 “在阿维塔上面&#xff0c;长安汽车、华为、宁德时代做了非常深层次的合作”&#xff0c;6月15日&#xff0c;阿维塔科技副总裁、首席营销官CMO 李鹏程称。当天&#xff0c;阿维塔邀请媒体走进深圳华为坂田基地的华为智能汽车解决方案展…

Autonomous Vehicles Learning Notes

文章目录 自动驾驶感知传感器多模态传感器融合BEVCorner Cases 缩写 未完待续。。。 自动驾驶 来自&#xff1a;浅谈自动驾驶技术与挑战 L0&#xff1a;主动刹车、盲点监测、车道偏离预警和车身稳定系统都属于 L0 级别的自动驾驶&#xff1b; L1&#xff1a;如车道保持系统&a…

MongoDB聚合查询(二)

MongoDB聚合查询 什么是聚合查询 聚合操作主要用于处理数据并返回计算结果。聚合操作将来自多个文档的值组合在一起&#xff0c;按条件分组后&#xff0c;再进行一系列操作&#xff08;如求和、平均值、最大值、最小值&#xff09;以返回单个结果。 MongoDB的聚合查询 聚合是…

springboot+vue学生档案借阅管理系统_8xpgg-

随着社会的不断进步与发展&#xff0c;人们对生活质量要求逐步提升。如果开发一款档案管理系统&#xff0c;可以让学生在最短的时间里享受到最好的服务&#xff1b;而开发本系统&#xff0c;又能够提高系统整体工作水平&#xff0c;简化工作程序&#xff0c;这对管理员和学生来…

【算法题】数组系列(找出数组中重复的数字、二维数组中的查找)

算法题 数组系列 一、找出数组中重复的数字1.1、题目1.2、解题思路1&#xff08;排序法&#xff09;1.3、解题思路2&#xff08;hash&#xff09;1.4、小结 二、二维数组中的查找2.1、题目2.2、理解题目2.3、解题思路2.3.1、暴力枚举2.3.2、二分查找2.3.3、对角线查询&#xff…

【数据结构与算法C++实现】3、排序算法

原视频为左程云的B站教学 以下所有的swap()函数&#xff0c;函数定义为 void swap(int& a, int& b) {int t a;a b;b t; } // 也可以用异或&#xff0c;但不能传入同一个变量&#xff0c;可以是不同变量相同值 void swap(int& a, int& b) {a a ^ b;b a ^ …