【C++ | 移动构造函数】一文了解C++11的 移动构造函数

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
⏰发布时间⏰:2024-06-12 23:36:22

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
    • ✨1.1 移动语义
    • ✨1.2 右值引用
  • 🎄二、移动构造函数(move constructor)
  • 🎄三、使用移动构造函数
  • 🎄四
  • 🎄五
  • 🎄六、



在这里插入图片描述

🎄一、概述

移动构造函数、移动赋值函数都是C++11增加的,了解这两个函数之前需要先弄清楚 移动语义右值引用

✨1.1 移动语义

移动语义是C++11才实现的,它的意义是对于一些即将被销毁的对象,可以不复制它,而是窃取它的资源,以此来减少一次复制,达到大幅度提升性能的效果。

在C++11标准之前,没有直接的方法移动对象,即使某些情况不需要拷贝对象,也不得不拷贝。例如,函数返回非引用的返回值时,会先构造一个临时对象作为返回值,函数调用时将该临时对象赋值给接收对象,调用结束后会销毁该临时对象。这里的临时对象是肯定会被销毁的,如果能够将临时对象的资源直接移交给接收对象,那么就可以减少一次拷贝。旧标准则只能拷贝,然后再销毁临时对象的资源。
在这里插入图片描述
C++11支持将即将被销毁的对象移动到接收对象,而不是复制。如下图,临时对象的资源被移动到接收对象,减少一次复制。
在这里插入图片描述
下面代码演示了复制的过程,等学习了下面的移动构造函数就可以编写移动的代码了。

// g++ 11_Copy_Constructor_Date.cpp
#include <iostream>
#include <stdio.h>
#include <string.h>using namespace std;#define MAX_NEW_MEM		(64*1000*1000)class CDate
{
public:CDate(int year, int mon, int day);	// 构造函数声明CDate(const CDate& date);			// 拷贝构造函数声明~CDate();							// 析构函数声明CDate operator+(int day);			// 加号运算符声明void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << ", this=" << this << endl;//cout << "Date: " << str << endl;}private:int m_year;int m_mon;int m_day;char *str;
};// 构造函数定义
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;str = new char[MAX_NEW_MEM];sprintf(str, "%4d.%02d.%02d", year,mon,day);cout << "Calling Constructor" << ", this=" << this <<endl;
}// 拷贝构造函数定义
CDate::CDate(const CDate& date)
{m_year = date.m_year;m_mon = date.m_mon;m_day = date.m_day;str = new char[MAX_NEW_MEM];memcpy(str, date.str, MAX_NEW_MEM);cout << "Calling Copy Constructor" << ", this=" << this << ", Copy Data" <<endl;
}// 析构函数定义
CDate::~CDate()
{cout << "Calling Destructor" << ", this=" << this <<endl;delete [] str;
}CDate CDate::operator+(int day)
{CDate temp = *this;temp.m_day += day;cout << "Calling operator+" << ", this=" << &temp << endl;return temp;
}int main()
{CDate date(2024,06,07);cout << endl;CDate date1 = std::move(date+1);// std::move 强制将 date+1 的求值结果转为右值date1.show();cout << endl;return 0;
}

运行结果如下:
1、std::move 强制将 date+1 的求值结果转为右值,避免编译器优化;
2、temp 对象赋值给date1之后,就销毁了,如果可以直接将temp对象的资源给到date1,就可以减少一次复制。
在这里插入图片描述


✨1.2 右值引用

前面介绍了C++11的移动语义,那这个移动语义是怎样实现的呢?

C++11标准引入的一种新的引用类型——右值引用,来实现移动操作。右值引用只能关联到右值,而右值要么是字面值,要么是求值过程中产生的临时对象。右值引用的定义使用了&&,可以参考下面代码:

int &&rri = 13; // 定义了右值引用 rri

上个小节的临时对象只会在程序中很短暂的停留,使用完之后会被立即销毁。C++11标准通过 右值引用 来完全地接管这些临时对象,然后将临时对象的资源 移动 到接收对象,并且要保证这个临时对象可以被正常销毁。这就是C++11标准实现移动语义的原理。

关于左值、右值、右值引用还有疑惑的,可以参考这篇文章:【C++ | 左值、右值】一文了解C++的左值、右值、左值引用(&)、右值引用(&&)


在这里插入图片描述

🎄二、移动构造函数(move constructor)

移动构造函数(move constructor),是C++11标准增加的在创建对象时移动旧对象资源的构造函数。

类的移动构造函数原型通常是这样的:类名(类名 &&);。以CDate类为例,其移动构造函数声明如下:

CDate(CDate &&date);

移动构造函数的几个特点:
1、函数名和类名相同,因为它也是构造函数的一种;
2、第一个参数必须是一个自身类类型的右值引用,且其他参数都有默认值。
3、第一个参数不能声明为 const 右值引用的原因是该引用在函数内会被修改(移动资源)。
4、移动构造函数执行后,需要保证右值引用的对象能够被正常销毁。

下面看看怎样声明定义自己的移动构造函数:

CDate::CDate(CDate&& date)
{m_year = date.m_year;m_mon = date.m_mon;m_day = date.m_day;str = date.str;date.str = NULL;cout << "Calling Move Constructor" << ", this=" << this <<endl;
}

移动构造函数解析:

  • 1、处理普通数据成员,直接使用旧对象的进行赋值;
  • 2、处理指向堆内存的指针,直接堆内存地址给新对象的指针,旧对象指针指向NULL。
    语句str = date.str;将旧对象的str直接给到正在创建的对象,而不重新new、复制。
    语句date.str = NULL;将旧对象的str赋值为NULL,保证其可以被正常销毁,delete NULL;delete[] NULL不会造成任何问题。

在这里插入图片描述

🎄三、使用移动构造函数

在这里插入图片描述

🎄四

在这里插入图片描述

🎄五

在这里插入图片描述

🎄六、

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

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

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

相关文章

[深度学习]使用python转换pt并部署yolov10的tensorrt模型封装成类几句完成目标检测加速任务

【简单介绍】 使用Python将YOLOv10模型从PyTorch格式&#xff08;.pt&#xff09;转换为TensorRT格式&#xff0c;并通过封装成类来实现目标检测加速任务&#xff0c;是一个高效且实用的流程。以下是该过程的简要介绍&#xff1a; 模型转换&#xff1a; 利用官方提供导出命令…

浅谈网络通信(2)

文章目录 一、TCP1.1、TCP提供的api —— ServerSocket 、Socket1.2、使用TCP协议编写回显服务器1.3、长/短连接 二、应用层协议、传输层协议详解2.1、应用层(后端开发必知必会)2.1.1、自定义应用层协议2.1.2、通用的协议格式2.1.2.1、XML2.1.2.2、json2.1.2.3、protobuffer 2.…

Protected and unprotected Meilisearch projects(/health)

Elasticsearch 做为老牌搜索引擎&#xff0c;功能基本满足&#xff0c;但复杂&#xff0c;重量级&#xff0c;适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求&#xff0c;极快&#xff0c;单文件&#xff0c;超轻量。 所以&#xff0c;对于中小型项目来说…

02通讯录管理系统——创建项目

创建项目步骤如下&#xff1a; 1.创建新项目 2.添加文件 2.1创建项目 打开vs2019后&#xff0c;点击创建新项目&#xff0c;创建新的C项目 填写项目名称&#xff0c;选择路径 2.2添加文件 添加成功后&#xff0c;效果如图

【QT5】<知识点> QT串口编程

目录 前言 一、串口编程步骤 0. 添加串口模块 1. 自动搜索已连接的串口 2. 创建串口对象 3. 初始化串口 4. 打开串口 5. 关闭串口 6. 发送数据 7. 接收数据 二、简易串口助手 1. 实现效果 2. 程序源码 3. 实现效果二 前言 本篇记录QT串口编程相关内容&#xff0…

React基础教程(06):Ref的应用

7、Ref的应用 7.1 给标签设置ref"username" 通过这个获取this.refs.username&#xff0c;ref可以获取到应用的真实dom <input style{{width:300}}ref{"text"}/> {/*非常推荐*/} <Button style{{backgroundColor:#2ba471, border:"none&qu…

毕业了!给学计算机朋友的 10 条血泪建议

大家好&#xff0c;我是程序员鱼皮。最近高考结束了&#xff0c;也有很多同学毕业了&#xff0c;首先祝福这些朋友在人生的新阶段一帆风顺。 刚参加完高考的朋友&#xff0c;面临的最大问题就是选专业&#xff0c;这段时间也有一些家长向我咨询&#xff1a;还能不能选计算机啦…

人脸匹配——OpenCV

人脸匹配 导入所需的库加载dlib的人脸识别模型和面部检测器读取图片并转换为灰度图比较两张人脸选择图片并显示结果比较图片创建GUI界面运行GUI主循环运行显示全部代码 导入所需的库 cv2&#xff1a;OpenCV库&#xff0c;用于图像处理。 dlib&#xff1a;一个机器学习库&#x…

基于深度学习视觉算法的多模型文件融合检测系统设计与实现及优化(工人姿态检测+安全帽佩戴检测系统)

1&#xff0c;融合pose.pt(姿态检测)(安全帽佩戴检测)效果图 实时检测优化后FPS可达20 2,原理介绍 YOLOv5是目前应用广泛的目标检测算法之一&#xff0c;其主要结构分为两个部分&#xff1a;骨干网络和检测头。 输入&#xff08;Input&#xff09;: YOLOv5的输入是一张RGB图像…

定档6.20,创邻科技图数据库先锋版发布会来了!

6月20日 14:00 &#xff0c;创邻科技将重磅召开 2024 Galaxybase银河图数据库先锋版发布会&#xff0c;戳此预约&#xff01; 书于竹帛&#xff0c;镂于金石&#xff0c;琢于盘盂。历史长河中&#xff0c;数据通过不同形态承载着人类文明&#xff0c;人们在数千年中始终保持着…

使用Python和Matplotlib绘制复杂数学函数图像

本文介绍了如何使用Python编程语言和Matplotlib库来绘制复杂的数学函数图像。通过引入NumPy库的数学函数,我们可以处理包括指数函数在内的各种复杂表达式。本文详细讲解了如何设置中文字体以确保在图像中正确显示中文标题和标签,并提供了一个完整的代码示例,用户可以通过输入…

找不到xinput1_3.dll文件要怎么修复?有哪些有效修复xinput1_3.dll文件的方法

要解决xinput1_3.dll文件缺失的问题&#xff0c;首先我们需要对这个文件有所了解。理解了这个文件的性质和作用后&#xff0c;才能更科学、有效地解决因其丢失而导致的问题。那么接下来&#xff0c;让我们不浪费时间&#xff0c;直接深入研究如何修复xinput1_3.dll文件的最佳方…

震坤行亮相2024成都工博会,赋能产业新发

为期3天的成都工博会于2024年4月23日在成都国际会展中心完美落幕。震坤行再次紧跟西部智能制造产业发展步伐&#xff0c;亮相现场&#xff0c;实力“圈粉”&#xff0c;为西部地区的制造企业带来打造了一场工业互联网盛宴。 本届成都工博会成功举办&#xff0c;展会聚集了各个国…

在ubuntu中恢复误删除的文件

1、安装 TestDisk 在 Ubuntu 上&#xff0c;可以使用以下命令安装 TestDisk&#xff1a; sudo apt-get install testdisk2、查询你删除的文件所在那个分区 #查询分区 df -h #我这里是/dev/sda2 #也可以使用下面命令查看具体哪个分区 lsblk3、查询该分区是什么系统类型 sudo …

java:【@ComponentScan】和【@SpringBootApplication】扫包范围的冲突

# 代码结构如下&#xff1a; 注意【com.chz.myBean.branch】和【com.chz.myBean.main】这两个包是没有生重叠的。 主程序【MyBeanTest1、MyBeanTest2、MyBeanTest3】这两个类是在包【com.chz.myBean.main】下 # 示例代码 【pom.xml】 org.springframework.boot spring-boot-…

java采集微信公众号数据

需求背景: 最新需要调用微信公众号api 去微信公众号采集 发布文章数据。 &#xff08;本片文章的意义&#xff1a;根据自己开发的方案来提供思路&#xff0c;当然那不会提供代码。代码是最没有 含金量的东西。&#xff09; 1:遇到的坑:首先 想到的是调用 https://api.weixin…

科技项目验收测试必须进行吗?软件测试公司推荐

科技项目验收测试是指在科技项目开发周期中&#xff0c;对项目完成后进行的一种测试和评估工作。它的目的是验证项目是否达到预期的要求&#xff0c;并确保项目交付给客户前达到预期的质量标准。 一、科技项目验收测试的必要性   科技项目验收测试是项目管理中不可或缺的一个…

Maven认识与学习

1. Maven介绍 1.2 初识Maven 1.2.1 什么是Maven Maven是Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 官网&#xff1a;Maven – Welcome to Apache Maven Apache 软件基金会&#xff0c;成立于1999年7月&#xff0c;是目前世界上最大的最受…

Linux C语言:变量的作用域和生命周期(auto、register、static和extern)

一、变量存储类型-auto 1、auto变量的说明 变量在程序中使用时,必须预先说明它们的存储类型和数据类型。 变量说明的一般形式是&#xff1a; <存储类型> <数据类型 > <变量名> &#xff1b; <存储类型>是关键词auto、register、static和extern<…

湘江早报专访惟客数据李柯辰:湖南伢子返湘玩转“AI+金融”

来源 |《湘江早报》 记者 | 黄荣佳 ​ 随着数字化浪潮的到来&#xff0c;AI的风吹遍了各行各业&#xff0c;金融作为对新兴技术最敏感的行业&#xff0c;前沿技术的赋能&#xff0c;让金融科技成为行业发展的“新赛点”。作为一家以大数据和AI人工智能技术驱动的新一代数字化…