c++深拷贝和浅拷贝

一、浅拷贝

  • 本质:简单地复制对象的成员值。如果成员里有指针,新对象和原对象的指针会指向同一块内存
    比如你有对象 A,里面指针 p 指向堆内存 0x123;用 A 拷贝出对象 BB 的指针 p 也指向 0x123

  • 问题

    • 若其中一个对象修改指针指向的内容,另一个对象也会受影响(因为共享内存)。
    • 当对象销毁时(调用析构函数),两个对象的指针会重复释放同一块内存,程序会崩溃(C++ 不允许重复释放同一块堆内存 )。

    类比:你和朋友共用一把家里的钥匙(指针),你把家里东西改了(修改内存内容),朋友看到的也会变;但如果你们先后 “销毁钥匙权限”(调用析构释放内存),第二次释放就会出问题。

二、深拷贝

  • 本质:给新对象的指针重新开一块独立的堆内存,再把原对象指针指向的内容完整复制到新内存里。
    还是用上面的例子:对象 A 指针 p 指向 0x123;拷贝出对象 B 时,B 会新申请一块内存 0x456,再把 0x123 里的内容复制到 0x456B 的指针 p 指向 0x456

  • 优点

    • 两个对象的指针各自指向独立内存,修改内容互不影响。
    • 析构时,各自释放自己的内存,不会重复释放,程序更安全。

    类比:你和朋友各自配一把钥匙(新内存),各自钥匙开各自家门(独立内存),改自己家东西不影响对方,销毁钥匙(析构)也不会冲突。

三、如何实现深拷贝?(以代码为例)

假设我们有一个简单的 STRING 类(简化版,类似你提供的代码):

cpp

运行

class STRING {
private:char* _str;  // 指向堆内存的指针
public:// 构造函数:初始化字符串STRING(const char* str) {_str = new char[strlen(str) + 1];  // 开堆内存存字符串strcpy(_str, str);}// 析构函数:释放堆内存~STRING() {delete[] _str;}// ... 其他成员函数
};
1. 深拷贝的拷贝构造函数

cpp

运行

STRING(const STRING& s) {// 1. 给新对象的指针开独立堆内存(大小和原字符串一样,+1 存 '\0')_str = new char[strlen(s._str) + 1];  // 2. 把原对象字符串内容,复制到新内存里strcpy(_str, s._str);  
}

作用:创建新对象时,不共用原对象内存,而是 “另开新内存 + 复制内容”,避免浅拷贝的问题。

2. 深拷贝的赋值运算符重载

cpp

运行

STRING& operator=(const STRING& s) {// 防御性检查:避免自己赋值给自己(比如 a = a; 这种情况,释放内存会出问题)if (this != &s) {  // 1. 先释放当前对象旧的堆内存(防止内存泄漏)delete[] _str;  // 2. 开新内存,复制内容(和拷贝构造逻辑一样)_str = new char[strlen(s._str) + 1];  strcpy(_str, s._str);  }return *this;  // 返回当前对象,支持链式赋值(比如 a = b = c; )
}

作用:处理 “对象赋值” 场景(比如 a = b; )。需要先释放自己旧的内存,再深拷贝新内容,否则会内存泄漏(旧内存没释放,又开新内存,原内存就丢了,无法释放 )。

四、总结

  • 浅拷贝:简单复制指针值,共享内存,容易出 “重复释放” 或 “内容互相影响” 的问题。
  • 深拷贝:给新对象指针重新开内存、复制内容,让对象互相独立,解决浅拷贝的隐患。
  • 实现关键:在拷贝构造函数赋值运算符重载里,手动 “开新内存 + 复制内容”,别依赖编译器默认的浅拷贝逻辑。

理解后,写涉及指针成员(动态内存)的类时,记得补全深拷贝的这两个函数,否则程序大概率会崩溃或内存泄漏~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90221.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NineData新增SQL Server到MySQL复制链路,高效助力异构数据库迁移

在实际的数据库迁移工作中,异构库之间的迁移常常被视为一项“高风险、高工作量、高复杂度”的挑战任务。这不仅是一次数据库切换,更是对系统稳定性、数据一致性、业务连续性和技术团队耐力的全方位考验。为解决企业在异构数据库迁移中的痛点,…

字符串和对象的深拷贝和浅拷贝

字符串和对象的深拷贝和浅拷贝【一】基本介绍【1】浅拷贝【2】深拷贝【二】字符串的拷贝【1】字符串的 “浅拷贝”【2】字符串的 “深拷贝”【三】对象的拷贝【1】浅拷贝(Shallow Copy)【2】深拷贝(Deep Copy)【四】字符串和对象拷…

4.5 优化器中常见的梯度下降算法

梯度下降算法(Gradient Descent)的数学公式可以通过以下步骤严格表达:1. 基本梯度下降(Batch Gradient Descent) 目标:最小化损失函数L(θ)\mathcal{L}(\theta)L(θ),其中 θ\thetaθ是模型参数…

AM1.5G AAA稳态太阳光模拟器特点

光谱匹配度AM1.5G AAA稳态太阳光模拟器的光谱分布严格匹配国际标准IEC 60904-9中的AM1.5G光谱(波长范围300-4000nm),确保与自然太阳光的偏差在25%以内(AAA级标准)。光谱匹配度通过精密滤光片和氙灯或LED组合光源实现&a…

OSPF开放式最短路径优先

1OSPF简介(1)OSPF英文全称Open Shortest Path First (开放式最短路径优先)(2)OSPF是IETF 开发的一种链路状态路由协议,使用基于带宽的度量值。(3)OSPF采用SPF算法计算路由,从算法上保…

Lua(模块与包)

Lua 模块的基本概念Lua 中的模块是一个由函数、变量组成的代码库,通常保存在独立的 .lua 文件中。模块通过 return 语句导出其内容,供其他脚本调用。模块化设计可以提高代码复用性,便于管理。创建模块模块通常以 .lua 文件形式存在&#xff0…

1. boost::asio之socket的创建和连接

网络编程基本流程 网络编程的基本流程对于服务端是这样的 服务端 1)socket——创建socket对象。 2)bind——绑定本机ipport。 3)listen——监听来电,若在监听到来电,则建立起连接。 4)accept——再创建一个…

WPF 控制动画开关

记录一种实现方式:第一步:首先定义一个静态类,提供依赖属性,进而方便在xaml中实现绑定:public static class AnimationBehavior{// 定义附加属性public static readonly DependencyProperty IsAnimatingProperty Depen…

元素竖向的百分比设定是相对于父容器的高度吗?

元素竖向的百分比设定是相对于父容器的高度吗? 核心问题 在CSS中,当设置元素的竖向属性(如height、padding-top等)为百分比值时,其计算基准是父容器的高度还是宽度? 权威结论height属性 百分比值基于父容器…

web3.0怎么入局

Web3.0(第三代互联网)融合了区块链、去中心化应用(DApps)、NFT、DAO等新兴技术,给个人和机构提供了许多全新的赚钱机会。入局 Web3.0 赚钱主要有以下几种途径,根据你的技术背景、资金能力和时间投入可以选择适合自己的方式。 目录 一、普通用户赚钱方式(门槛低) 1. …

linux入门 相关linux系统操作命令(二)--文件管理系统 ubuntu22.04

以下有免费的4090云主机提供ubuntu22.04系统的其他入门实践操作 地址:星宇科技 | GPU服务器 高性能云主机 云服务器-登录 相关兑换码星宇社区---4090算力卡免费体验、共享开发社区-CSDN博客 兑换码要是过期了,可以私信我获取最新兑换码!&a…

Python-初学openCV——图像预处理(二)

目录 一、图像仿射变换 1、基本性质 二、cv2.warpAffine() 函数 1、图像旋转 2、图像平移 3、图像缩放 4、图像剪切 三、 插值方法 1、最近邻插值 2、双线性插值 3、像素区域插值 4、双三次插值 5、Lanczos插值 一、图像仿射变换 仿射变换(Affine Tr…

医疗AI轻量化部署方案的深度梳理与优化路径判研

摘要 医疗AI的快速发展为精准诊断、个性化治疗和医疗资源优化提供了新机遇。然而,大规模模型的高计算复杂度和资源需求限制了其在资源受限环境(如边缘设备、基层医疗机构)的应用。本文系统梳理了医疗AI轻量化部署的核心技术体系,包括模型压缩、参数高效微调(PEFT)、边缘-…

SSP通过SDK对接流量的原理与实现

一、核心概念解析 1.1 SSP(供应方平台) 定义:SSP是程序化广告生态中媒体方的核心工具,通过自动化技术帮助媒体(如网站、应用、视频平台)管理广告资源、优化填充率并最大化广告收益。核心功能:…

如何清理电脑c盘内存 详细操作步骤

电脑使用时间不断延长,许多用户可能会遇到一个问题——C盘空间不足,导致系统运行缓慢或无法安装新程序。如果C盘的存储空间被大量占用,可能会影响到计算机的性能。本文将介绍几种有效的方法,帮助你清理C盘内存,释放空间…

ESP32的ADF详解:5. Streams的API

一、算法流 (algorithm stream) 1. 初始化与配置API功能描述关键参数说明algo_stream_init()初始化算法流(AEC/AGC/NS/VAD)config->algo_mask 选择算法组合config->sample_rate 设置采样率(默认16kHz)config->partition_…

JavaScript对象键序问题解析

问题的发现: 我有一个接口返回一个json数据浏览器network里的Response里是从大到小排。 但Preview就是反过来的 问题的描述: 上面那个让我发现浏览器处理对象或者json是会对其键值对做排序!!! 在JavaScript中&am…

pandas库的数据导入导出,缺失值,重复值处理和数据筛选,matplotlib库 简单图绘制

目录 一.数据导入导出 1.CSV文件读取与参数说明 2.Excel与TST文件读取 3.数据导出操作 二.缺失值处理 1.填充缺失值 2.删除缺失值【删除整行数据】 三.重复值处理 四.数据筛选与条件查询 1.逻辑判断取数 2.字符匹配 3.逻辑运算: &(和&…

FPGA 如何实现另一个 FPGA?

如果你对 FPGA 有些了解,大概知道它的意思是“可编程逻辑器件”,可以把写好的逻辑电路(通常是 Verilog/VHDL)通过工具综合、布局布线、烧写进去,让一块芯片变成“你想要的电路”。但如果我告诉你,现在有个开…

文思助手、新华妙笔 AI材料星的公文写作深度测评

公文写作一直都是体制内工作人员的日常核心任务,写公文的难点不仅来自于对政策表述严谨性的高要求,也在于格式规范、内容深度以及效率压力的多重考验。随着AI技术的发展,越来越多的文字辅助工具出现,很大程度的缓解了写作压力&…