【C++】023、移动语义深拷贝

发布时间:2026/9/28 18:39:03

【C++】023、移动语义深拷贝
一、移动语言是如何解决深拷贝的性能问题深拷贝会复制整个底层数据让源对象和目标对象都拥有自己独立的堆内存空间移动语义是转换底层资源的所有权将源对象的指针指向目标对象而不赋值底层数据时间复杂都为1移动语义将源对象的资源指针移动到目标对象并将源对象指针设置为nullptr这样源对象的析构操作就不会释放已经释放的资源了。二、代码示例移动构造函数与移动赋值操作符函数实现#include iostream #include cstring class MyString { private: char* m_data; size_t m_len; public: // ---------- 构造函数 ---------- MyString(const char* str ) : m_len(strlen(str)), m_data(new char[m_len 1]) { strcpy(m_data, str); } // ---------- 析构函数 ---------- ~MyString() { delete[] m_data; // 如果 m_data 是 nullptr安全无操作 } // // 1. 深拷贝构造O(n)昂贵 // MyString(const MyString other) : m_len(other.m_len), m_data(new char[m_len 1]) { strcpy(m_data, other.m_data); // 申请内存 复制数据 std::cout 深拷贝构造耗时 O(n) std::endl; } // // 2. 移动构造O(1)零开销 // MyString(MyString other) noexcept : m_data(other.m_data) // ① 窃取指针只复制地址 , m_len(other.m_len) { // ② 窃取长度 other.m_data nullptr; // ③ 关键置空源对象切断所有权 other.m_len 0; std::cout 移动构造O(1) 指针交换未复制任何数据 std::endl; } // // 3. 移动赋值O(1)对比深拷贝赋值 // MyString operator(MyString other) noexcept { if (this ! other) { delete[] m_data; // 释放自己的旧资源如果有 m_data other.m_data; // 窃取指针 m_len other.m_len; other.m_data nullptr; // 置空源对象 other.m_len 0; std::cout 移动赋值O(1) std::endl; } return *this; } };外部调用代码int main() { std::cout 场景1拷贝构造 vs 移动构造 std::endl; { MyString s1(HelloWorld); // 1. 普通构造分配堆内存 MyString s2(s1); // 2. 深拷贝构造申请新内存 复制10个字符 MyString s3(std::move(s1)); // 3. 移动构造只交换指针O(1) // 注意s1 现在是一个空壳m_data nullptr不能再读取其内容 // 如果取消下面这行注释程序会崩溃访问空指针。 // std::cout s1 内容: s1.c_str() std::endl; std::cout s2 内容: s2.c_str() (独立内存) std::endl; std::cout s3 内容: s3.c_str() (窃取了 s1 的资源) std::endl; } // 作用域结束s1(空)、s2、s3 各自析构不会双重释放 std::cout std::endl;三、移动语义操作中置空源对象的原因1、防止双重释放如果源对象的析构函数被调用时m_data还指向原来的地址他就会delete[]这块内存而目标对象也指向这块地址两个析构先后释放同一块内存进程立即崩溃。2、保证析构安全置空后源对象的析构函数执行delete[] m_data由于m_data是nullpdelete[]是无害的空操作。四、移动构造函数使用noexcept的原因C标准库承诺vector扩容必须提供强异常安全保证也就是扩容过程中如果抛出异常程序的状态必须安全地恢复到扩容前的状态但是移动构造函数会将源对象置为空了无法恢复所以加noexcept相当于向编译器承诺此操作不会抛异常让stl容器放心地使用移动从而达到最高性能。

相关新闻

MateBook E Go触摸屏故障分析与修复记录

MateBook E Go触摸屏故障分析与修复记录

2026/8/14 2:09:21

设备型号 GK-W7X | 主机名 matebookeGO | 记录日期 2026-08-05 最终状态:完成服务恢复和自动重启策略配置后,电脑已重新启动;用户确认触摸屏恢复正常。 结论:触摸屏硬件和 HID/SPI/I2C 设备链正常。直接故障是 HuaweiThpSer…

自然语言操控电脑 OpenClaw v2.9.0 Windows 与 Mac 双端部署指南

自然语言操控电脑 OpenClaw v2.9.0 Windows 与 Mac 双端部署指南

2026/8/19 8:26:26

🔥前言:Win11 环境运行 OpenClaw 必读说明 OpenClaw(因其图标形似小龙虾,在社区中常被昵称为"小龙虾")是一款备受瞩目的本地优先AI智能体项目。该项目基于开源协议开发,能够通过自然语言指令驱动…

本地离线 AI 智能体 OpenClaw v2.9.0 Windows 一键部署全流程

本地离线 AI 智能体 OpenClaw v2.9.0 Windows 一键部署全流程

2026/9/8 4:24:51

核心亮点:提供全程可视化的图形操作界面,自动补齐全套运行依赖,数据独立存储于本地设备,兼容多款主流大模型,并采用轻量化的 45.7MB 整合压缩包。 教程适配:OpenClaw | 适配 Windows 10/11 与 macOS 双系统…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/28 4:08:17

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/28 16:01:49

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/28 2:15:29

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/28 3:14:54

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/28 3:58:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/28 3:47:14

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/28 16:01:48

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/28 5:05:21

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/28 16:01:48

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…