C++ 学习之深拷贝 和 浅拷贝
前言
在C++中,浅拷贝和深拷贝是涉及对象复制的两种不同方式,它们之间的关键区别在于拷贝对象时是否复制对象所指向的数据。
正文
浅拷贝(Shallow Copy):
- 浅拷贝只复制对象本身,而不复制对象所指向的数据。
- 当你使用浅拷贝创建一个新对象时,它将与原始对象共享相同的数据。这意味着如果一个对象修改了共享数据,另一个对象也会受到影响,因为它们指向相同的内存位置。
- 浅拷贝通常是通过默认的复制构造函数或赋值操作符来执行的。
深拷贝(Deep Copy):
- 深拷贝复制对象本身以及对象所指向的数据。它创建了一个新的独立副本,而不是与原始对象共享数据。
- 深拷贝确保原始对象和新对象是完全独立的,修改一个对象不会影响另一个对象。
- 深拷贝通常需要自定义复制构造函数和赋值操作符,以确保数据的完全复制。
分析代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
// 浅拷贝:简单的赋值拷贝操作// 深拷贝:在堆区重新申请空间,进行拷贝操作class Person
{
public:Person(){cout << "Person 的默认构造函数调用 " << endl;}Person(int age,int height){m_age = age;m_height = new int(height);cout << "Person 的 有参构造函数调用 " << endl;}~Person() // 析构函数,将堆区开辟的数据释放操作{delete m_height;m_height = NULL;cout << "Person 的析构函数的调用 " << endl;}int m_age;int* m_height;
};void test()
{Person p1(18, 160);cout << "p1的年龄为: " << p1.m_age << " 身高为 " << *p1.m_height << endl;Person p2(p1);cout << "p2的年龄为: " << p2.m_age << " 身高为 " << *p2.m_height << endl;
}int main()
{test();
}
上面那个代码会报错,为什么呢,因为上面是浅拷贝操作, p1 和 p2 的 指针 m_height 都指向同一个地址,当调用析构函数的时候,在 函数 test 里面 p1 和 p2 都是存储在栈里面的,先释放 p2 的空间 , 这导致后来 p1 无法释放 m_height 指向的空间
会产生上面的报错
我们可以通过 将
delete m_height;m_height = NULL;
改成
if (!m_height){delete m_height;m_height = NULL;}
浅拷贝带来的问题就是 堆区内存的重复释放带来的问题
利用深拷贝操作
我们可以写 拷贝函数 ,不使用默认的构造函数来实现深拷贝
Person(const Person& p){cout << " Person 的 拷贝函数的调用 " << endl;m_age = p.m_age;// m_height = p.m_height; 编译器默认实现的就是这行代码// 自己实现深拷贝操作m_height = new int(*p.m_height);}
我们来看看具体的代码实现
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
// 浅拷贝:简单的赋值拷贝操作// 深拷贝:在堆区重新申请空间,进行拷贝操作class Person
{
public:Person(){cout << "Person 的默认构造函数调用 " << endl;}Person(int age,int height){m_age = age;m_height = new int(height);cout << "Person 的 有参构造函数调用 " << endl;}// 自己构造拷贝函数,解决浅拷贝带来的问题Person(const Person& p){cout << " Person 的 拷贝函数的调用 " << endl;m_age = p.m_age;// m_height = p.m_height; 编译器默认实现的就是这行代码// 自己实现深拷贝操作m_height = new int(*p.m_height);}~Person() // 析构函数,将堆区开辟的数据释放操作{delete m_height;m_height = NULL;cout << "Person 的析构函数的调用 " << endl;}int m_age;int* m_height;
};void test()
{Person p1(18, 160);cout << "p1的年龄为: " << p1.m_age << " 身高为 " << *p1.m_height << endl;Person p2(p1);cout << "p2的年龄为: " << p2.m_age << " 身高为 " << *p2.m_height << endl;
}int main()
{test();
}
这样 p1 和 p2 的 m_height 指向的堆的内存地址就不一样了,代码就不会报错了
相关文章:

C++ 学习之深拷贝 和 浅拷贝
前言 在C中,浅拷贝和深拷贝是涉及对象复制的两种不同方式,它们之间的关键区别在于拷贝对象时是否复制对象所指向的数据。 正文 浅拷贝(Shallow Copy): 浅拷贝只复制对象本身,而不复制对象所指向的数据。…...
Qt QtWidgets相关问题汇总
问:在Qt QWidget中设置WindowFlags为Qt::Window导致该Widget消失了,为什么? 答:WindowFlags设置为Qt::Window,表示该widget变为window类型,需要调用QWidget::show()方法。 问:Qt中WindowFlags…...

【ubuntu22.04 文件管理器nautilus配置默认终端为alacritty】
前言 ubuntu默认的终端不能通过设置里的默认应用程序配置nautilus是ubuntu自带的文件管理器,包管理器里面只有nautilus-extension-gnome-terminal而没有提供大多终端update-alternatives工具可以修改系统的默认终端(ctrl-alt-t),但对nautilus文件管理器…...
信息化发展30
IT 治理的内涵 IT 治理作为组织上层管理的一个有机组成部分, 由组织治理层或高级管理层负责, 从组织全局的高度上对组织信息化与数字化转型做出制度安排, 体现了治理层和最高管理层对信息相关活动的关注;IT 治理强调数字目标与组…...
css溢出隐藏的五种方法
一、文本溢出 当容器中的文本内容超出容器的宽度或高度时,就会出现文本溢出的情况。下面介绍几种CSS实现文本溢出的方法。 单行文本溢出省略: 单行文本溢出省略通常用于标题等文本显示,可以通过设置white-space和text-overflow属性实现。w…...
RK3568-UART通信
RK3568-UART通信 1. 功能特点 RK3568有10个UART控制器,对应设备树里的uart0-uart9。 Rockchip UART (Universal Asynchronous Receiver/Transmitter) 基于16550A串口标准,支持以下 功能: 包含2组64字节的 FIFO,用于接收和传输支…...

武警三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课
部队三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课 现在不管什么GIS平台首先要解决的就是数据来源问题,因为没有数据的GIS就是一个空壳,下面我就目前一些主流的数据获取 方式了解做如下之我见(主要针对互联网上的一些…...

【Linux从入门到精通】通信 | 共享内存(System V)
本篇文章接着上篇文章通信 | 管道通信(匿名管道 & 命名管道)进行讲解。本篇文章的中点内容是共享内存。 文章目录 一、初识与创建共享内存 1、1 什么是共享内存 1、2 共享内存函数 1、2、1 创建共享内存 shmget 1、2、2 ftok 生成 key 1、2、3 获取共…...

ubuntu 扩展内存挂载
一般新建虚拟机时,系统默认的空间是20G,但是当我们搭建一些环境之后,需要解压一些稍微大点的源码时内存可能不够用了,这时我们需要扩展内存。 一、硬盘扩展 首先,关闭虚拟机,在虚拟机设置中将硬盘容量扩展…...

聚观早报|小米14渲染图曝光;蚂蚁金融大模型正式发布
【聚观365】9月9日消息 小米14渲染图曝光 蚂蚁金融大模型正式发布 路特斯推出全电动轿车Emeya 上汽集团8月整车销量42.3万辆 ChatGPT网站流量连续三个月下滑 小米14渲染图曝光 高通旗下全新一代旗舰芯片骁龙8 Gen3将于10月24-26日举办的骁龙技术峰会上亮相,相…...
musl libc 动态加载:默认链接脚本
前言 当前动态链接与静态链接应用程序时,均手动指定了链接脚本 使用 musl ldso 动态加载,发现不指定 链接脚本,编译后的 动态链接与静态链的应用程序依旧可以工作 那么不指定链接脚本,应用程序就没有链接操作了?还是有个默认的链接脚本? 经过实际验证,原来 musl gcc 工具…...
快速排序(递归和非递归两种方法实现)
快速排序: 1.首先找一个基准点(一般选取最左边第一个) 2.先从后往前遍历,找到第一个小于基准值的元素; 3.再从前往后,找到第一个大于基准值的元素; 4.将这两个元素两两交换 5.当i与j相遇时…...

ApiPost7使用介绍 | HTTP Websocket
一、基本介绍 创建项目(团队下面可以创建多个项目节点,每个项目可以创建多个接口): 参数描述库(填写参数时自动填充描述): 新建环境(前置URL、环境变量很有用)&#x…...

Linux常用命令——convertquota命令
在线Linux命令查询工具 convertquota 把老的配额文件转换为新的格式 补充说明 convertquota命令用于将老的磁盘额数据文件(“quota.user”和“quota.group”)转换为新格式的文件(“quota.user”和“quota.group”)。 语法 c…...

Linux 进程基础概念-进程状态、进程构成、进程控制
目录 Linux 进程 进程基础概念 进程状态 进程的构成 进程控制 进程创建和终止 Linux 进程 参考: 「linux操作系统」进程的切换与控制到底有啥关系? - 知乎 (zhihu.com),Linux进程解析_deep_explore的博客-CSDN博客,腾讯面试…...

Unity Animation、Animator 的使用
文章目录 1. 添加动画2. Animation2.1 制作界面2.2 制作好的 Animation 动画2.3 添加和使用事件 3. Animator3.1 制作界面3.2 一些参数解释3.3 动画参数 4. Animator中相关类、属性、API4.1 类4.2 属性4.3 API4.4 几个关键方法 5. 动画播放和暂停控制 1. 添加动画 选中待提添加…...

Flink--2、Flink部署(Yarn集群搭建下的会话模式部署、单作业模式部署、应用模式部署)
星光下的赶路人star的个人主页 你必须赢过,才可以说不在乎输赢 文章目录 1、Flink部署1.1 集群角色1.2 Flink集群搭建1.2.1 集群启动1.2.2 向集群提交作业 1.3 部署模式1.3.1 会话模式(Session Mode)1.3.2 单作业模式(Per-Job Mod…...
执行Django 的迁移命令报错[1193, Unknown system variable default_storage_engine]
在学习“”编写你的第一个 Django 应用程序,第2部分”时候,遇到一个问题。 执行迁移命令 python manage.py makemigrations polls 后,报错: migrations.py:109: RuntimeWarning: Got an error checking a consistent migration …...
Himall商城-公共方法
目录 1 Himall商城-公共方法 1.1 /// 根据订单id获取订单项 1.2 /// 根据订单项id获取售后记录 1.3 /// 判断订单是否正在申请售后 Himall商城-公共方法 #region 公共方法 public static List<InvoiceTitleInfo> GetInvoiceTitles(long userid) {...

海域可视化监管:浅析海域动态远程视频智能监管平台的构建方案
一、方案背景 随着科技的不断进步,智慧海域管理平台已经成为海洋领域监管的一种重要工具。相比传统的视频监控方式,智慧海域管理平台通过建设近岸海域视频监控网、海洋环境监测网和海上目标探测网络等,可实现海洋管理的数字化转型。 传统的…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...