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

C++深拷贝\浅拷贝

C++ 中的深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是指在对象复制时,对象成员的复制方式不同。理解这两种拷贝构造方式非常重要,尤其是在涉及到动态内存分配和资源管理时。

浅拷贝(Shallow Copy)

浅拷贝是指在拷贝对象时,只复制对象的,但对于指针类型的成员变量,拷贝的是指针的地址,即两个对象的指针成员指向同一块内存区域。

浅拷贝的特点:
  • 复制对象的值,包括原始数据的成员。
  • 对于指针成员,只复制指针的值(地址),导致两个对象的指针指向同一块内存。
  • 这种方式可能会导致资源的共享和管理上的问题,尤其是在对象销毁时,如果多个对象指向同一块内存,可能会发生“双重释放”错误。
浅拷贝示例:
#include <iostream>
using namespace std;class Student {
public:int num;int *age;  // 指针成员,假设它指向动态分配的内存// 构造函数Student(int n, int a) {num = n;age = new int;  // 动态分配内存*age = a;}// 浅拷贝构造函数Student(const Student &other) {num = other.num;age = other.age;  // 只是拷贝指针的值(地址),没有进行深拷贝}// 析构函数~Student() {delete age;  // 释放内存}
};int main() {Student s1(1001, 20);Student s2 = s1;  // 调用浅拷贝构造函数cout << "s1: " << s1.num << ", " << *s1.age << endl;cout << "s2: " << s2.num << ", " << *s2.age << endl;// s1和s2的age指针指向同一块内存区域// 修改s1的age的值会影响s2的age,因为它们共享同一内存*s1.age = 25;cout << "After modifying s1.age:" << endl;cout << "s1: " << s1.num << ", " << *s1.age << endl;cout << "s2: " << s2.num << ", " << *s2.age << endl;// 程序结束时,s1和s2的析构函数都会被调用,导致删除同一块内存
}
结果:
s1: 1001, 20
s2: 1001, 20
After modifying s1.age:
s1: 1001, 25
s2: 1001, 25

问题

  • s1s2age 指针指向同一块内存,因此修改一个对象的 age 会影响另一个对象。
  • 当程序结束时,两个对象都调用析构函数,释放同一块内存(发生双重释放错误)。

深拷贝(Deep Copy)

深拷贝是指在拷贝对象时,除了复制值之外,还会对指针类型成员指向的内存进行复制。每个对象会有自己独立的内存,不会出现共享资源的问题。

深拷贝的特点:
  • 对象成员的所有值都会被复制。
  • 对于指针成员,会重新分配内存并复制数据,确保每个对象都有自己的内存。
  • 不会发生资源共享问题,因此避免了“双重释放”的错误。
深拷贝示例:
#include <iostream>
using namespace std;class Student {
public:int num;int *age;  // 指针成员// 构造函数Student(int n, int a) {num = n;age = new int;  // 动态分配内存*age = a;}// 深拷贝构造函数Student(const Student &other) {num = other.num;age = new int;  // 为指针成员重新分配内存*age = *(other.age);  // 复制数据,而不是指针地址}// 析构函数~Student() {delete age;  // 释放内存}
};int main() {Student s1(1001, 20);Student s2 = s1;  // 调用深拷贝构造函数cout << "s1: " << s1.num << ", " << *s1.age << endl;cout << "s2: " << s2.num << ", " << *s2.age << endl;// s1和s2的age指针指向不同的内存区域// 修改s1的age的值不会影响s2*s1.age = 25;cout << "After modifying s1.age:" << endl;cout << "s1: " << s1.num << ", " << *s1.age << endl;cout << "s2: " << s2.num << ", " << *s2.age << endl;
}
结果:
s1: 1001, 20
s2: 1001, 20
After modifying s1.age:
s1: 1001, 25
s2: 1001, 20

解释

  • s1s2age 指针指向不同的内存区域,因此修改 s1age 不会影响 s2
  • 由于使用深拷贝,s1s2 在析构时会分别释放各自的内存,不会发生双重释放问题。

总结:

  • 浅拷贝:只复制对象的值,对于指针成员,复制的是指针的地址,导致多个对象共享相同的内存。
  • 深拷贝:复制对象的值,对于指针成员,重新分配内存并复制数据,确保每个对象有独立的内存,避免了资源共享的问题。

自定义拷贝构造函数

为了避免浅拷贝带来的问题,特别是当对象中有动态分配的内存时,通常需要自己定义深拷贝构造函数。同时,还需要实现赋值操作符重载,以确保在对象赋值时,拷贝也是深拷贝。

class Student {
public:int num;int *age;Student(int n, int a) {num = n;age = new int;*age = a;}// 深拷贝构造函数Student(const Student &other) {num = other.num;age = new int;*age = *(other.age);}// 赋值操作符重载(深拷贝)Student& operator=(const Student &other) {if (this != &other) {  // 防止自赋值num = other.num;delete age;  // 释放旧的内存age = new int;  // 分配新内存*age = *(other.age);}return *this;}~Student() {delete age;  // 释放内存}
};

这样,无论是通过拷贝构造函数还是赋值操作符,都能确保每个对象都拥有自己独立的内存,避免了资源管理的冲突和双重释放问题。

相关文章:

C++深拷贝\浅拷贝

C 中的深拷贝&#xff08;Deep Copy&#xff09;和浅拷贝&#xff08;Shallow Copy&#xff09;是指在对象复制时&#xff0c;对象成员的复制方式不同。理解这两种拷贝构造方式非常重要&#xff0c;尤其是在涉及到动态内存分配和资源管理时。 浅拷贝&#xff08;Shallow Copy&…...

本地文件共享——HFS

目录 1.介绍&#xff1a; 2.下载&#xff1a; 3.开始使用&#xff1a; 1.介绍&#xff1a; HFS&#xff08;HTTP File Server&#xff09;是一款轻量级的本地文件共享软件&#xff0c;主要用于快速搭建一个基于网页的临时文件服务器&#xff0c;支持通过浏览器直接上传或下载…...

第十二届先进制造技术与材料工程国际学术会议 (AMTME 2025)

重要信息 大会官网&#xff1a;www.amtme.org&#xff08;了解会议&#xff0c;投稿等&#xff09; 大会时间&#xff1a;2025年3月21-23日 大会地点&#xff1a;中国-广州 简介 2025年第十二届先进制造技术与材料工程 (AMTME 2025) 定于2025年3月21-23日在中国广州隆重举…...

【Alertmanager】alertmanager告警系统原理剖析与应用实战,应有尽有非常全面

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...

C语言预处理学习笔记

1. 预处理器的功能 预处理器&#xff08;Preprocessor&#xff09;在编译C语言程序之前对源代码进行预处理。预处理指令以#号开头&#xff0c;主要包括文件包含、宏定义、条件编译等功能。 2. 文件包含 文件包含功能用于在一个文件中包含另一个文件的内容&#xff0c;通常用…...

jQuery AJAX 方法详解

jQuery AJAX 方法详解 引言 随着互联网技术的不断发展,前端开发领域的技术也在不断更新迭代。jQuery 作为一种广泛使用的前端JavaScript库,极大地简化了DOM操作和事件处理。在众多jQuery功能中,AJAX(Asynchronous JavaScript and XML)方法尤为突出,它允许我们在不重新加…...

C++之虚函数、虚函数表

C 虚函数、虚函数表详解与实践 C中虚函数是实现多态的重要技术&#xff0c;接下来将从汇编、以及gdb调试运行方面下手全面了解虚函数、虚函数表、以及虚函数调用。 原理初认识 一个由虚函数的类将会有一个虚函数表&#xff0c;且所有该类的实例化对象共享一个虚函数表。虚函…...

零基础学QT、C++(一)安装QT

目录 如何快速学习QT、C呢&#xff1f; 一、编译器、项目构建工具 1、编译器&#xff08;介绍2款&#xff09; 2、项目构建工具 二、安装QT 1、下载QT安装包 2、运行安装包 3、运行QT creator 4、导入开源项目 总结 闲谈 如何快速学习QT、C呢&#xff1f; 那就是项目驱动法&…...

Python SMTP 实现邮件发送功能

发送邮件的流程 登录我们邮箱&#xff0c; 书写接收者的邮箱&#xff0c; 书写题目与内容&#xff0c;添加附件&#xff0c; 点击发送。 邮件协议 smtp 是邮件发送的协议。pop3 是邮件接收的协议。 smtplib模块用法 创建协议对象&#xff1a;smtpObj smtplib.SMTP() 创建…...

低价窜货要如何管控

在竞争激烈的市场环境中&#xff0c;低价与窜货就像一对如影随形的“孪生兄弟”&#xff0c;给品牌的健康发展带来了极大的困扰。低价销售不仅压缩了合理的利润空间&#xff0c;破坏了市场的价格体系&#xff0c;还会引发恶性竞争&#xff0c;让整个市场陷入混乱无序的状态。而…...

如何看nginx.conf文件?

是的&#xff0c;你的理解是对的&#xff01;在 Nginx 配置中&#xff0c;最内层的 location 确实是决定请求最终处理的“入口”。当请求进入 Nginx 时&#xff0c;Nginx 会根据请求的路径&#xff08;即 URL&#xff09;匹配 location 块&#xff0c;然后按照匹配的顺序逐层向…...

Linux中POSIX应用场景

Linux 提供了丰富的 POSIX&#xff08;Portable Operating System Interface&#xff09;标准接口&#xff0c;这些接口可以帮助开发者编写可移植、高效的应用程序。POSIX 标准定义了一系列系统调用和库函数&#xff0c;涵盖了文件操作、进程管理、线程管理、信号处理、同步机制…...

《动手学机器人学》笔记

目录 0.介绍1.概述&#xff5c;空间位置、姿态的描述&#xff08;33&#xff09;&#xff5c;《动手学机器人学》2.&#xff08;2&#xff09;-Robotics Toolbox①&#xff08;V10.4&#xff09;3.齐次坐标与变换矩阵4.一般形式的旋转变换矩阵5.&#xff08;轴角法&#xff09;…...

国产编辑器EverEdit - 文本编辑器的关键特性:文件变更实时监视,多头编辑不掉坑

1 监视文件变更 1.1 应用场景 某些时候&#xff0c;用户会使用多个编辑器打开同一个文件&#xff0c;如果在A编辑器修改保存&#xff0c;但是B编辑器没有重新打开&#xff0c;直接在B编辑器修改再保存&#xff0c;则可能造成在A编辑器中修改的内容丢失&#xff0c;因此&#x…...

化学蛋白质组学与药物靶点筛选:DARTS、LiP-MS、TPP、CETSA技术的深度解析

更多详情请看&#xff1a;LiP-MS药物靶点筛选技术 在药物研发的复杂过程中&#xff0c;药物靶点的筛选是关键环节之一。化学蛋白质组学技术的出现&#xff0c;为药物靶点筛选提供了强大的工具&#xff0c;化学蛋白质组学是一门研究细胞或组织中全部蛋白质的化学组成、结构、功…...

如何使用 Flutter DevTools 和 PerformanceOverlay 监控性能瓶颈

使用 Flutter DevTools 和 PerformanceOverlay 监控性能瓶颈&#xff1a;详细分析与实战 在开发 Flutter 应用时&#xff0c;性能问题可能会导致用户体验下降&#xff0c;比如页面卡顿、掉帧、内存泄漏等。为了定位和解决这些问题&#xff0c;Flutter 提供了强大的性能监控工具…...

为AI聊天工具添加一个知识系统 之113 详细设计之54 Chance:偶然和适配 之2

本文要点 要点 祖传代码中的”槽“ &#xff08;占位符变量&#xff09; 和 它在实操中的三种槽&#xff08;占据槽&#xff0c;请求槽和填充槽&#xff0c; 实时数据库&#xff08;source&#xff09;中数据(流入 ETL的一个正序流程 行列并发 靶向整形 绑定变量 &#xff09…...

HTML5 面试题

1. HTML5 新增了哪些重要特性&#xff1f; 语义化标签&#xff1a;这些标签有助于提高页面的可读性和可维护性。多媒体支持&#xff1a;HTML5 引入了 和 标签&#xff0c;可以直接嵌入音频和视频文件&#xff0c;无需依赖插件。本地存储&#xff1a;引入了 localStorage 和 se…...

鸿蒙初学者学习手册(HarmonyOSNext_API14)_自定义动画API(@ohos.animator (动画) )

前言 在纯血鸿蒙中最具有用户特色的效果就是自定义的动画效果。在纯血鸿蒙中有多种定义方式&#xff0c;但是今天介绍的是ApI中的自定义动画。 注意: 动画本身具有生命周期&#xff0c;但是不支持在UIAbility的文件使用&#xff0c;简单而言就是不允许在UIAbility生命周期中…...

PINN求解一维burgers方程

PINN求解一维burgers方程 模型搭建网络与训练结果可视化对比实际结果 完整代码下载链接 PINN求解一维burgers方程 模型 搭建网络与训练 #########-------------- python求解一维burgers方程-------------------################## # -*- coding: utf-8 -*- import os os.envi…...

Linux系统配置阿里云yum源,安装docker

配置阿里云yum源 需要保证能够访问阿里云网站 可以先ping一下看看&#xff08;阿里云可能禁ping&#xff0c;只要能够解析为正常的ip地址即可&#xff09; ping mirrors.aliyun.com脚本 #!/bin/bash mkdir /etc/yum.repos.d/bak mv /etc/yum.repos.d/*.repo /etc/yum.repos…...

Android 动态加入Activity 时 manifest 注册报错解决。使用manifestPlaceholders 占位

需求如下&#xff1a; 项目 测试demo 有多个渠道&#xff0c;部分渠道包含支付功能&#xff0c;在主测试代码外&#xff0c;需要一个单独 Activity 调用测试代码。 MainActivityPayActivity渠道A包含不包含渠道B包含包含 因为支付功能需要引入对应的 moudule&#xff0c;因此…...

【找工作】C++和算法复习(自用)

文章目录 C头文件自定义排序函数stl 算法树状数组 自用随便记录 C 排序 stl 头文件 全能头文件&#xff1a; #include<bits/stdc.h>自定义排序函数 bool compare(const int &odd1,const int &odd2) {return odd1>odd2; }stl 枚举map map<int, strin…...

【相聚青岛】人工智能与材料国际学术会议即将召开

一、大会简介 人工智能与材料国际会议&#xff08;ICAIM 2025&#xff09; 官方网站&#xff1a;www.ic-aim.net 官方邮箱&#xff1a;icaim2025163.com 会议时间&#xff1a;2025年3.21-24 会议地点&#xff1a;中国青岛 会议检索&#xff1a;EI检索 截稿时间&#xff1a;2月…...

BFS 解决 FloodFill 算法(典型算法思想)—— OJ例题算法解析思路

目录 一、733. 图像渲染 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; 算法思路 基础参数 函数入口 检查条件 初始化 BFS BFS 填充过程 返回结果 复杂度分析 总结 二、200. 岛屿数量 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a;…...

纷析云开源版- Vue2-增加字典存储到localStorage

main.js //保存字典数据到LocalStorage Vue.prototype.$api.setting.SystemDictType.all().then(({data}) > {loadDictsToLocalStorage(data) })新增 dictionary.js 放在 Utils文件夹里面 // 获取字典数据 export function getDictByType(dictType) {const dicts JSON.par…...

Python 爬虫selenium

1.selenium自动化 selenium可以操作浏览器&#xff0c;在浏览器页面上实现&#xff1a;点击、输入、滑动 等操作。 不同于selenium自动化&#xff0c;逆向本质是&#xff1a; 分析请求&#xff0c;例如&#xff1a;请求方法、请求参数、加密方式等。用代码模拟请求去实现同等…...

前端导出word文件,并包含导出Echarts图表等

基础导出模板 const html <html><head><style>body {font-family: Times New Roman;}h1 {text-align: center;}table {border-collapse: collapse;width: 100%;color: #1118FF;font-weight: 600;}th,td {border: 1px solid black;padding: 8px;text-align: …...

【复现DeepSeek-R1之Open R1实战】系列8:混合精度训练、DeepSpeed、vLLM和LightEval介绍

这里写目录标题 1 混合精度训练1.1 FP16和FP321.2 优点1.3 存在的问题1.4 解决办法 2 DeepSpeed3 vLLM3.1 存在的问题3.2 解决方法3.2.1 PagedAttention3.2.2 KV Cache Manager3.2.3 其他解码场景 3.3 结论 4 LightEval4.1 主要功能4.2 使用方法4.3 应用场景 本文继续深入了解O…...

从面试中的“漏掉步骤”谈自我表达与思维方式的转变

在今天的面试中&#xff0c;我遇到了一个让我深刻反思自己思维方式的问题。当面试官问到如何应对用户量和请求量逐渐增加时&#xff0c;我的回答遗漏了一些基础步骤&#xff0c;导致我给出了“我暂时想不出更好的反思”的回答。这一经历让我意识到&#xff0c;在面对问题时&…...