news 2026/4/15 15:24:01

C++ 拷贝构造函数到底什么时候被调用?看这 3 种典型场景(附完整示例)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 拷贝构造函数到底什么时候被调用?看这 3 种典型场景(附完整示例)

🧠 C++ 拷贝构造函数到底什么时候被调用?看这 3 种典型场景(附完整示例)

在 C++ 中,拷贝构造函数(Copy Constructor)是对象复制时的关键机制。很多初学者容易混淆“初始化”和“赋值”,也不清楚函数传参或返回时是否真的触发了拷贝。今天我们结合一段经典代码,彻底讲清楚!

🔧 示例类定义
#include <iostream> usingnamespacestd; class Person { public: Person() { cout << "无参构造函数!" << endl; mAge = 0; } Person(int age) { cout << "有参构造函数!" << endl; mAge = age; } Person(const Person& p) { cout << "拷贝构造函数!" << endl; mAge = p.mAge; } ~Person() { cout << "析构函数!" << endl; } public: int mAge; };

这个类能清晰打印出每种构造/析构的调用过程,非常适合教学。


✅ 场景一:用已有对象初始化新对象

void test01() { Person p1(20); // 有参构造 Person p2(p1); // 👉 调用拷贝构造 //Person newman2 = man; // 👉 也调用拷贝构造(等价于上一行) // ❌ 注意:以下不是拷贝构造! // Person newman3; // newman3 = man; // 这是赋值操作,调用 operator= }

✨ 关键点:只有在对象“创建时”用另一个对象初始化,才触发拷贝构造
A = B如果 A 已存在,就是赋值,不是构造!


✅ 场景二:函数参数按值传递

void doWork(Person p1) {} // 参数是值传递 void test02() { Person p; // 无参构造 doWork(p); // 👉 调用拷贝构造,为 p1 创建副本 }

💡 如果你看到函数内部修改了p1但不影响原对象,就是因为这里拷贝了一份。
想避免拷贝?改用const Person& p1


✅ 场景三:函数按值返回局部对象

Person doWork2() { Person p1; cout << "局部对象地址: " << &p1 << endl; return p1; // 理论上应拷贝 } void test03() { Person p = doWork2(); // 👉 理论上调用拷贝构造 cout << "外部对象地址: " << &p << endl; }

⚠️但实际运行时,你可能看不到“拷贝构造函数!”的输出!
原因:现代编译器会进行返回值优化(RVO),C++17 更是强制省略拷贝(guaranteed copy elision)。
所以p直接在doWork2()中构造,零拷贝

🔬 想验证拷贝是否发生?编译时加-fno-elide-constructors(GCC/Clang)即可关闭优化。


📌 总结:拷贝构造的三大调用时机

场景

是否调用拷贝构造

说明

Person p2(p1)

Person p2 = p1

✅ 是

对象初始化

函数参数按值传递foo(p1)

✅ 是

创建形参副本

函数返回局部对象return obj

❓ 可能被优化

C++17 起通常不调用

p2 = p1;(已存在对象)→ 调用赋值运算符,不是拷贝构造


💡 小贴士

  • 如果你的类管理资源(如指针、文件句柄),必须自定义拷贝构造,否则浅拷贝会导致 double-free 等严重 bug。

  • C++11 后还可定义移动构造函数,进一步提升性能。

  • 编译器优化是好事,但理解底层语义才能写出安全高效的代码!


通过这段代码 + 三个测试函数,你就能彻底掌握拷贝构造的调用逻辑。快去试试test01()test02()test03(),观察输出吧!

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

Android USB相机开发实战:从零构建OTG摄像头集成方案

Android USB相机开发实战&#xff1a;从零构建OTG摄像头集成方案 【免费下载链接】Android-USB-OTG-Camera 项目地址: https://gitcode.com/gh_mirrors/an/Android-USB-OTG-Camera 在移动设备功能日益丰富的今天&#xff0c;Android USB相机开发为开发者提供了突破设备…

作者头像 李华
网站建设 2026/4/11 0:50:25

Simple Live:全平台直播聚合神器,打造你的专属观影空间

还在为切换不同直播平台而烦恼吗&#xff1f;是否厌倦了在手机、电脑和电视之间来回折腾的观看体验&#xff1f;Simple Live 正是为你量身打造的解决方案&#xff01;这款基于 Flutter 开发的跨平台直播聚合工具&#xff0c;让你在任何设备上都能享受虎牙、斗鱼、哔哩哔哩、抖音…

作者头像 李华
网站建设 2026/4/13 21:24:32

5分钟搞定乱码难题:ConvertToUTF8插件完全指南

还在为打开文件时看到一堆乱码而头疼吗&#xff1f;&#x1f92f; 特别是处理中文、日文、韩文等非UTF-8编码的文件时&#xff0c;这个问题尤为突出。ConvertToUTF8正是为解决这个痛点而生的Sublime Text插件&#xff0c;它能智能检测并转换各种字符编码&#xff0c;让乱码问题…

作者头像 李华
网站建设 2026/4/11 20:54:10

OWASP DependencyCheck深度解析:构建企业级软件供应链安全防护体系

在现代软件开发的生命周期中&#xff0c;开源组件的安全风险已成为企业面临的重要挑战。OWASP DependencyCheck作为一款专业的软件成分分析工具&#xff0c;通过自动化检测依赖中的已知问题&#xff0c;为开发团队提供可靠的供应链安全保障。 【免费下载链接】DependencyCheck …

作者头像 李华
网站建设 2026/4/14 6:52:46

2026亚洲艺术电影节「乡土纪事单元」评委亮相!

在高速流动的全球化时代&#xff0c;总有人俯身倾听土地的声音。 2026亚洲艺术电影节设立「乡土纪事单元」&#xff0c; 聚焦村庄、方言、家族与风物—— 那些朴素影像里&#xff0c;藏着一个民族最深的呼吸。 三位来自中国与印度的艺术家以美术、表演和镜头&#xff0c; 回望故…

作者头像 李华
网站建设 2026/4/11 17:02:16

水泥搅拌机数据采集远程监控系统方案

随着国家大规模基础设施建设的不断推进&#xff0c;水泥搅拌机作为关键施工设备&#xff0c;其市场需求呈现出持续增长的趋势。然而&#xff0c;这一增长态势也给设备制造商带来了运维服务上的巨大挑战。由于水泥搅拌机项目遍布全国各地&#xff0c;设备分布广泛且分散&#xf…

作者头像 李华