当前位置: 首页 > news >正文

小学生学C++编程语法知识(C++中的深拷贝与浅拷贝)


C++中的深拷贝与浅拷贝

——给同学们讲一下“复制魔法”

同学们,今天我们学习一个非常重要的C++知识:

当我们复制一个对象时,到底是复制“外表”,还是复制“里面的东西”?


这就是:

  • 浅拷贝(Shallow Copy)

  • 深拷贝(Deep Copy)


它们主要和:

  • 指针

  • 动态内存(new)

  • 类对象复制

有关。


一、先理解什么叫“拷贝”?

生活中:

小明有一本《C++魔法书》。

小红说:

“我也想要一本一样的。”

于是小明复制了一本。

这就是:

复制 = 拷贝

C++里面:

Student a; Student b = a;

意思:

把对象a复制给对象b。


例如:

int a = 10; int b = a;

结果:

a: 10 b: 10

两个数字互不影响。


如果:

b = 20;

那么:

a: 10 b: 20

没有问题。

因为:

int里面保存的是数据本身。


二、问题出现:指针!

看一个例子:

int a = 100; int *p = &a;

内存:

a ┌─────┐ │100 │ └─────┘ ↑ | p

指针p保存的是:

地址

不是100。


现在:

int *q = p;

发生什么?

100 ┌─────┐ │ │ └─────┘ ↑ ↑ | | p q

p和q:

指向同一个地方。

这就是:

浅拷贝


三、什么是浅拷贝?

一句话:

只复制地址,不复制真正的数据。


比如:

class Student { public: int age; int *score; };

创建:

Student s1; s1.age = 10; s1.score = new int(100);

内存:

s1 age ┌────┐ │10 │ └────┘ score | ↓ ┌─────┐ │100 │ └─────┘

现在:

Student s2 = s1;

默认拷贝:

C++会这样:

s2.age = s1.age s2.score = s1.score

结果:

s1.score | ↓ ┌─────┐ │100 │ └─────┘ ↑ | s2.score

两个指针:

指向同一个100。


四、浅拷贝有什么问题?

看代码:

#include<iostream> using namespace std; class Student { public: int *score; Student() { score = new int(100); } ~Student() { delete score; } }; int main() { Student a; Student b = a; }

发生什么?

创建a:

a.score | ↓ 100

复制b:

a.score | ↓ 100 ↑ | b.score

程序结束:

先销毁b:

delete score;

100被释放。


然后销毁a:

再次:

delete score;

可是:

这个内存已经没有了!

这叫:

重复释放


可能导致:

  • 程序崩溃

  • 内存错误


五、什么是深拷贝?

深拷贝:

一句话:

不仅复制地址,而是重新复制一份数据。


还是刚才例子:

a:

a.score | ↓ 100

复制:

Student b=a;

深拷贝以后:

a.score | ↓ ┌─────┐ │100 │ └─────┘ b.score | ↓ ┌─────┐ │100 │ └─────┘

注意:

两个100:

是两块不同的内存。


六、如何实现深拷贝?

需要自己写:

拷贝构造函数


格式:

类名(const 类名 &对象) { }

例如:

#include<iostream> using namespace std; class Student { public: int *score; Student() { score = new int(100); } //拷贝构造函数 Student(const Student &s) { score = new int(*s.score); } ~Student() { delete score; } }; int main() { Student a; Student b=a; }

关键:

score = new int(*s.score);

拆开:

第一步:

取出原来的值:

*s.score

得到:

100

第二步:

重新申请空间:

new int(100)

得到新的:

100

所以:

两个对象:

互不影响。


七、浅拷贝 vs 深拷贝

比较浅拷贝深拷贝
复制什么地址数据
速度
是否申请新空间
两个对象是否共享数据
容易出错吗容易安全
需要自己写吗默认提供通常自己写

八、生活中的比喻

浅拷贝:

小明有一个遥控汽车。

小红复制:

拿了一张纸:

写:

遥控汽车的位置:小明家

这不是复制汽车。

只是复制地址。


深拷贝:

小红:

重新买了一辆一模一样的汽车。

现在:

小明玩自己的。

小红玩自己的。

互不影响。


九、什么时候需要深拷贝?

主要情况:

类里面有指针

例如:

class Array { int *data; };

或者:

动态数组:

int *arr=new int[100];

或者:

字符串:

char *name;

都需要考虑深拷贝。


十、C++中的“三件套”

如果一个类管理动态内存:

通常需要:

1. 构造函数

申请空间:

new

2. 拷贝构造函数

负责:

深拷贝

3. 析构函数

释放空间:

delete

这三个叫:

Rule of Three(三法则)


十一、给同学们的记忆口诀

普通变量,直接复制。 指针变量,要看地址。 复制地址,是浅拷贝。 复制数据,是深拷贝。 new出来的东西, 一定要小心释放。

十二、信奥竞赛中的理解

在GESP、CSP-J阶段:

通常:

  • int

  • double

  • char

  • string

  • vector

已经帮我们处理好了。

例如:

vector<int> a; vector<int> b=a;

这里:

不是简单复制地址。

vector内部已经实现了深拷贝。

所以:

b[0]=100;

不会影响:

a[0]

但是学习:

  • 链表

  • 二叉树

  • 动态数组

  • 智能指针

时:

深浅拷贝就是必须掌握的核心知识。


一句话总结:

浅拷贝复制“钥匙”(地址),深拷贝复制“房子”(数据)。
指针越多,越要小心浅拷贝。


http://www.jsqmd.com/news/1331933/

相关文章:

  • 浏览器插件原理与实战:安全获取无水印媒体资源的技术解析
  • C#在AI基础设施层的工程化实践:从ONNX模型服务到高性能推理
  • TwinCAT3 TCP/IP自由协议通讯:从原理到工程实践
  • 智慧果园桃子成熟度检测数据集:1245张图像,覆盖三种关键采摘期
  • 抗冲击儿童近视防控镜片推荐 - 中媒介
  • 2026年南通市海安市铝艺大门定制厂家优选指南 - geo交流
  • 模型安全输入过滤网关——基于正则与轻量级分类器的 Prompt 注入防护
  • Unitree G1 强化学习实战:从 IsaacLab 训练到 MuJoCo Sim2Sim 验证
  • 四层高功率PCB内层电源/地层铺铜工艺规范
  • Python数据分析实战:用迈克尔·杰克逊Billboard榜单数据学习数据可视化全流程
  • 基于多模态AI与智能体框架的长视频语义理解与内容提取实战
  • TEMU店群自动化管理系统:夜间全自动客服,3分钟内回复率100%
  • 工程机械润滑油哪家专业? - 中媒介
  • 饰面板使用寿命长哪家专业? - 中媒介
  • Unity多人游戏开发实战:基于Photon PUN2的状态同步与网络架构解析
  • 相机标定核心:内参、外参与畸变系数的原理与OpenCV实战
  • TDSQL分布式数据库部署实战:从架构设计到集群运维全解析
  • HAL库学习笔记
  • 华三交换机三权分立配置实战:基于RBAC实现网络设备精细化权限管理
  • Lenovo Legion Toolkit终极指南:轻量化硬件控制工具完全解析
  • ArcGIS捕捉功能全解析:从基础操作到拓扑数据构建实战
  • 作业失败一键根因:智能诊断的证据链设计与 33 次带标准答案的实测
  • 看不见的“植筋”有多重要?一个细节决定夹层寿命! - 名字不是很重要
  • 解决Ubuntu虚拟机拖放失效:VMware/VirtualBox增强工具完整修复指南
  • 固态继电器(SSR)原理、选型与应用实战指南
  • 洛阳装修验收严格哪家专业? - 中媒介
  • 5G基站开关电源工作状态异常导致小区频闪退服案例
  • 微信ClawBot技术解析:开源AI模型与微信生态的平民化AI代理实践
  • PostgreSQL 16核心特性解析:逻辑复制、性能优化与实战升级指南
  • Java NumberFormatException深度解析:从异常原理到防御性编码实战