news 2026/4/1 19:03:52

从拷贝到移动:C++ 移动构造与移动赋值是怎么被逼出来的?(附完整示例)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从拷贝到移动:C++ 移动构造与移动赋值是怎么被逼出来的?(附完整示例)

很多人在学习 C++ 时,第一次看到下面这两个函数会一脸懵:

Box(Box&& other); // 移动构造 Box& operator=(Box&& other); // 移动赋值

这两个函数看起来像“高级语法”,
但实际上它们不是凭空出现的,而是被性能问题 + 临时对象浪费一步步逼出来的进化结果。

本文从“问题”出发,再用一个完整可运行的例子把它讲透。

一、最初阶段:只有拷贝构造

最早 C++ 只有拷贝语义:

Box(const Box& other);

含义就是:

复制一份资源

示例:

Box a(10); Box b = a; // 拷贝构造

如果资源很小,问题不大。
但当成员是:

  • std::string
  • std::vector
  • 大数组
  • 文件句柄
  • 网络连接

复制就会变得慢 + 占内存

二、问题升级:临时对象的浪费

看一个常见函数:

Box createBox() { Box b(10); return b; }

调用:

Box a = createBox();

如果只有拷贝构造,流程是:

构造 b 拷贝构造 a 析构 b

问题在于:

b 马上要死了,还完整复制一份资源,纯浪费。

于是一个需求出现了:

能不能不复制,而是“搬走资源”?

三、移动语义诞生 —— “搬家”而不是“复印”

移动语义的核心思想:

如果对象马上要被销毁,就不要复制资源,直接转移所有权。

这就引出了移动构造移动赋值

四、完整示例代码(核心)

下面是一个完整可运行的类,包含:

  • 构造
  • 拷贝构造
  • 移动构造
  • 拷贝赋值
  • 移动赋值
  • 析构
#include <iostream> using namespace std; class Box { public: int* data; // 构造 Box(int v) { data = new int(v); cout << "构造\n"; } // 拷贝构造 Box(const Box& other) { data = new int(*other.data); cout << "拷贝构造\n"; } // 移动构造 Box(Box&& other) { data = other.data; // 接管资源 other.data = nullptr; // 清空对方 cout << "移动构造\n"; } // 拷贝赋值 Box& operator=(const Box& other) { cout << "拷贝赋值\n"; if (this == &other) return *this; delete data; data = new int(*other.data); return *this; } // 移动赋值 Box& operator=(Box&& other) { cout << "移动赋值\n"; if (this == &other) return *this; delete data; // 释放旧资源 data = other.data; // 接管资源 other.data = nullptr; // 清空对方 return *this; } ~Box() { delete data; cout << "析构\n"; } }; Box createBox() { Box b(10); return b; } int main() { cout << "=== 移动构造示例 ===\n"; Box a = createBox(); // 触发移动构造(或RVO) cout << "=== 移动赋值示例 ===\n"; Box b(1); b = createBox(); // 触发移动赋值 }

五、可能看到的输出

不同编译器略有差异,常见输出:

=== 移动构造示例 === 构造 移动构造 析构 析构 === 移动赋值示例 === 构造 构造 移动赋值 析构 析构

有时你只会看到:

构造

那是RVO(返回值优化)在工作 ——
编译器直接在目标位置构造对象,连移动都省掉了。

六、移动构造 vs 移动赋值区别

类型场景是否已有资源核心动作
移动构造新对象创建没有直接接管资源
移动赋值对象已存在

先释放再接管

七、为什么要把对方清空?

other.data = nullptr;

原因:

不清空 → 析构 double free 清空 → delete nullptr 安全

八、现实类比

拷贝构造 = 复印整箱书 移动构造 = 把箱子搬走 拷贝赋值 = 先扔旧书再复印新书 移动赋值 = 先扔旧书再搬新箱子

九、终极锚点总结

拷贝构造 → 复制资源 移动构造 → 搬资源给新对象 拷贝赋值 → 复制资源给已有对象 移动赋值 → 清空自己再搬资源

移动语义不是复杂语法,
它是“拷贝太贵”被逼出来的性能进化。

当你理解:

资源复制 vs 资源转移

移动构造和移动赋值就再也不会混了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 16:31:45

大数据毕设选题推荐:基于springboot+大数据的果园管理系统基于springboot+数据可视化的果园果树的生长信息管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/26 10:28:49

大数据计算机毕设之基于springboot+大数据的果园管理系统_数据可视化大屏分析系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/31 19:59:03

设计副业技能匹配工具,输入自身技能,匹配需求副业,标注技能提升方向,帮助从业者发挥优势,提升副业竞争力。

1. 实际应用场景描述 场景&#xff1a; 小李是一名 UI 设计师&#xff0c;平时工作稳定&#xff0c;但想利用业余时间发展副业&#xff0c;增加收入。他不确定自己的技能适合哪些副业&#xff0c;也不知道该往哪个方向提升技能来接更高价值的项目。 目标&#xff1a; 通过输入 …

作者头像 李华
网站建设 2026/3/31 21:48:46

Plotly + Dash:构建交互式数据仪表盘的艺术与实战

目录 摘要 1 引言&#xff1a;为什么Dash是现代数据可视化的终极选择 1.1 Dash的核心价值定位 1.2 技术演进路线 2 Dash架构深度解析 2.1 核心架构设计理念 2.1.1 Dash应用架构层次 2.1.2 Dash应用架构图 2.2 回调函数机制深度解析 2.2.1 回调函数工作原理 2.2.2 回…

作者头像 李华
网站建设 2026/3/30 3:18:50

LLM支持的AI Agent实体链接技术

LLM支持的AI Agent实体链接技术 关键词&#xff1a;LLM&#xff08;大语言模型&#xff09;、AI Agent、实体链接技术、知识图谱、自然语言处理 摘要&#xff1a;本文聚焦于LLM支持的AI Agent实体链接技术&#xff0c;详细阐述了该技术的背景、核心概念、算法原理、数学模型等内…

作者头像 李华