[C++] 浅拷贝和深拷贝
浅拷贝只是简单的值拷贝;
深拷贝需要重新分配空间。
系统默认的拷贝构造函数属于浅拷贝。
#include <iostream> using namespace std; class A { public: char *p; A(char *a) { int len = strlen(a) + 1; p = new char[len]; memcpy(p, a, len); } void print(void) { cout << p << endl; } }; int main(void) { A m("Hello"); m.print(); // 使用系统默认的拷贝构造函数 A n(m); n.print(); // 修改对象m的成员变量,对象n的也随之改变 strcpy(m.p, "World"); m.print(); n.print(); }
输出结果为:
Hello
Hello
World
World
为什么修改对象 m 的值,对象 n 的值也随之改变?
原因是在创建对象 m 时,构造函数中为其分配了所需要的内存空间,对象 m 的成员变量指针 p 会指向分配内存空间的首地址;
当使用默认的拷贝构造函数,利用对象 m 初始化对象 n 时,只是简单的将对象 n 的成员变量指针 p 也指向对象 m 分配的内存空间的首地址;
两个指针指向同一个内存空间,当其中任意一个对象修改了内存空间中的值,另一个也随之改变。
浅拷贝的影响:
如果在类的析构函数中 delete 内存,那么同一块内存会被销毁两次,这样会导致系统错误。
如果想要在修改其中一个对象时而不影响另一个对象,就要使用深拷贝,也就是自定义拷贝构造函数,在拷贝构造函数中为新对象重新分配内存空间。
#include <iostream> using namespace std; class A { public: char *p; A(char *a) { int len = strlen(a) + 1; p = new char[len]; memcpy(p, a, len); } // 自定义拷贝构造函数,深拷贝 A(const A &a) { int len = strlen(a.p) + 1; // 重新分配内存空间 p = new char[len]; memcpy(p, a.p, len); } void print(void) { cout << p << endl; } }; int main(void) { A m("Hello"); m.print(); // 使用自定义的拷贝构造函数 A n(m); n.print(); // 修改对象m的成员变量,对象n的不会改变 strcpy(m.p, "World"); m.print(); n.print(); }
输出结果为:
Hello
Hello
World
Hello
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2017-12-22 Linux 利用busybox制作根文件系统