c++深拷贝和浅拷贝的区别_c++拷贝构造函数与赋值运算符【核心】

发布时间 - 2025-12-27 00:00:00    点击率:
深拷贝与浅拷贝的本质区别在于是否为动态资源重新分配独立内存:浅拷贝仅复制指针值导致共享堆内存,易引发野指针和double free;深拷贝则为每个对象单独分配并拷贝内容,需手动实现拷贝构造函数和赋值运算符,并注意自赋值、资源释放与异常安全;现代C++推荐使用RAII(如vector、unique_ptr)避免手写深拷贝。

深拷贝和浅拷贝的本质区别在于:是否为对象内部的动态资源(比如 new 出来的内存)重新分配独立空间。浅拷贝只复制指针值,多个对象共用同一块堆内存;深拷贝则为每个对象单独 new 一份,互不干扰。

浅拷贝:默认行为,危险但高效

编译器自动生成的拷贝构造函数和赋值运算符,执行的是位拷贝(bitwise copy)。如果类里有指针成员,它只复制指针地址,不复制指针指向的内容。

后果很直接:两个对象的指针指向同一块内存。一旦其中一个 delete 了,另一个再访问就是野指针;析构两次还会导致程序崩溃(double free)。

常见触发场景:

  • 用一个已存在的对象初始化新对象:A a2 = a1;
  • 函数按值传参:func(a1);(形参调用拷贝构造)
  • 函数返回局部对象:return a;(返回时可能调用拷贝构造)

深拷贝:手动实现,安全但需谨慎

必须显式定义拷贝构造函数和赋值运算符,在函数体内对指针成员用 new 分配新内存,并把原数据逐字节拷贝过去(比如用 memcpy 或循环赋值)。

关键点:

  • 拷贝构造函数参数必须是 const A&,避免无限递归
  • 赋值运算符要先检查自赋值:if (this == &rhs) return *this;
  • 赋值前要释放原有资源,防止内存泄漏
  • 两者都要确保异常安全(比如 new 失败时已有资源不泄露)

现代C++的更优解:移动语义 + RAII

手动写深拷贝容易出错,C++11 后推荐用智能指针(std::unique_ptrstd::shared_ptr)或容器(std::vectorstd::string)管理资源。它们自带正确的拷贝/移动逻辑。

例如:

  • std::vector 替代 int* + size_t
  • std::unique_ptr 替代裸指针,拷贝被禁用,移动自动转移所有权
  • 这样就不用手写拷贝构造和赋值运算符,也避免了浅拷贝陷阱

怎么判断自己需要深拷贝?

看类里有没有“裸”动态资源:

  • new / malloc 分配的内存,且没交给 RAII 对象管理 → 需要深拷贝
  • 只有基本类型、std 容器、智能指针 → 默认拷贝是安全的,无需额外操作
  • 不确定?加个日志在析构函数里打印地址,观察两个对象析构时是否释放同一块地址

基本上就这些。深浅拷贝不是语法题,而是资源管理意识的问题。写类时先想清楚“我的对象拥有哪些资源”,再决定要不要接管拷贝逻辑。


# 字节  # ai  # c++  # 区别  # red  # String  # 运算符  # 赋值运算符  # if  # 构造函数  # 析构函数  # const  # 递归  # int  # double  # 循环  # 指针  #   # 形参  # copy  # delete  # 对象  # this  # 则为  # 的是  # 都要  # 多个  # 已有  # 还会  # 推荐使用  # 两次 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  Bootstrap整体框架之CSS12栅格系统  微信小程序 五星评分(包括半颗星评分)实例代码  如何用好域名打造高点击率的自主建站?  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  如何在服务器上配置二级域名建站?  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  如何在IIS中配置站点IP、端口及主机头?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  个人网站制作流程图片大全,个人网站如何注销?  网站制作报价单模板图片,小松挖机官方网站报价?  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  历史网站制作软件,华为如何找回被删除的网站?  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  如何用PHP快速搭建高效网站?分步指南  Laravel如何自定义错误页面(404, 500)?(代码示例)  高性能网站服务器部署指南:稳定运行与安全配置优化方案  javascript中闭包概念与用法深入理解  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  如何用VPS主机快速搭建个人网站?  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  php 三元运算符实例详细介绍  如何用虚拟主机快速搭建网站?详细步骤解析  如何用花生壳三步快速搭建专属网站?  网站建设保证美观性,需要考虑的几点问题!  Laravel如何使用查询构建器?(Query Builder高级用法)  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  在线制作视频网站免费,都有哪些好的动漫网站?  Linux安全能力提升路径_长期防护思维说明【指导】  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  大型企业网站制作流程,做网站需要注册公司吗?  Laravel怎么使用artisan命令缓存配置和视图  如何在服务器上三步完成建站并提升流量?  bootstrap日历插件datetimepicker使用方法  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  EditPlus中的正则表达式 实战(2)  使用C语言编写圣诞表白程序  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  微信小程序 配置文件详细介绍  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  如何撰写建站申请书?关键要点有哪些?