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

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

目录

1.string类的模拟实现 

1.1经典的string类问题

1.2浅拷贝

1.3深拷贝

 1.3.1传统版本写法的String类

1.3.2现代版写法的String类

1.3写时拷贝(了解)

2.扩展阅读:


【揭秘!】这里有你从未听过的独特见解,快来点赞关注,开启智慧之旅

1. 经典的string类问题

//为了和标准库区分,此处使用String
class String
{
public:/*String():_str(new char[1]){*_str = '\0'}*///String(const char* str = '\0') 错误示范//String(const char* str = nullptr)错误示范String(const char* str = ""){//构造String类对象时,如果传递nullptr指针,可以认定程序非法if(ptr == nullptr){assert(false);return ;}_str = new char[strlen(str) + 1];strcpy(_str,str);}~String(){if(_str){delete[] _str;_str = nullptr;}}
private:char* _str;
};//测试
void TsstString()
{String s1("hello cx");String s2(s1);
}

说明:上述String类没有显示定义其拷贝构造函数与赋值运算符重载,此时编译器会合成默认的,当是s1构造s2时,编译器会调用默认的拷贝构造。最终导致的问题是,s1、s2共用同一块内存空间,在释放时同一块空间被释放多次而引起程序崩溃,这种拷贝方式称为浅拷贝。

2. 浅拷贝

浅拷贝也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以继续对资源进行操作时,就会发生访问违规。

就像一个家庭中有两个孩子,但父母只买了一份玩具,两个孩子愿意一起玩,则万事大吉,万一不想分享就你争我夺,玩具损坏。

可以采用深拷贝解决浅拷贝的问题,即:每个对象都有一份独立的资源,不要和其他对象共享。

父亲给每给每个孩子都买一份玩具,各自玩各自的就不会有问题了。

3. 深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显示给出。一般情况都是按照深拷贝方式提供。

 3.1 传统版本写法的String类

class String
{
public:String(const char* str =""){//构造String类对象时,如果传递nullptr指针,可以认为程序非法if(nullptr == str){assert(false);return ;}_str = new char[strlen(str)+1];strcpy(_str,str);}String(const String& s): _str(new char[strlen(s._str)+1]{strcpy(_str,s._str);}String& operator=(const String& s){if(this != &s){char* pStr = new char[strlen(s._str)+1];strcpy(pStr,s._str);delete[] _str;_str = pStr; }return *this;}~String(){if(_str){delete[] _str;_str = nullptr;}}private:char* _str;
};

3.2 现代版写法的String类

class String
{
public:String(const char* str = "") {if (nullptr == str){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}String(const String& s):_str(nullptr){String strTmp(s._str);swap(_str, strTmp._str);}//对比下面和上面的赋值哪个实现比较好String& operator=(String s){swap(_str, s._str);return *this;}//String& operator=(const String& s)//{//	if (this != &s)//	{//		String strTmp(s);//		swap(_str, strTmp._str);//	}//	return *this;//}~String(){if (_str){delete[] _str;_str = nullptr;}}private:char* _str;
};

4. 写时拷贝(了解)

 写时拷贝就是一种拖延,是在浅拷贝的基础上增加了引用计数的方式来实现的。

引用计数:用来记录资源使用者的个。在构造时,将资源的技计数给成1,每增加一个对象使用该资源时,就给计数增加1,当某个对象销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象是资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源。

写时拷贝

写时拷贝在读取时的缺陷

5. 扩展阅读:

面试中string的一种正确写法

 STL中的string类怎么了

 用心呈现,只为遇见更好的你!点赞关注,让我们的博客陪伴你成长!

http://www.xdnf.cn/news/130303.html

相关文章:

  • 【现代深度学习技术】循环神经网络06:循环神经网络的简洁实现
  • 头歌实训之索引
  • MySQL 库的操作 -- 增删改查,备份和恢复,系统编码
  • 深度解析之算法之分治(快排)
  • Python-36:饭馆菜品选择问题
  • 使用jsrsasign进行RSA加密解密
  • Vue 2 和 Vue 3 的详细对比,从 生命周期、API、响应式系统、函数调用 等多角度展开,最后附表格总结
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第三模块·面向对象深度进化 —— 第十二章 接口:比C函数指针更强大的契约
  • 数学基础 -- 欧拉公式的推导过程学习
  • 精准落地设计,现代项目管理中的深度实践
  • FeignClient用法笔记
  • 构建企业官方网站有哪些必备因素?
  • YOLOv8融合CPA-Enhancer【提高恶略天气的退化图像检测】
  • ecovadis认证需要提供哪些文件?ecovadis认证优势是什么?
  • c语言 write函数
  • Java线程池那点事(面试高频)
  • ASR VAD TTS
  • VLA 论文精读(十八)π0.5: a Vision-Language-Action Model with Open-World Generalization
  • JavaFX 第三篇 HostServices和Platform
  • 交通运输行业综合智慧监管平台:商贸物流的安全与效率引擎
  • Windows下QT打包后程序运行后弹出CMD命令窗口的问题解决方法
  • vxe-table封装表头
  • MSHFlexGrid 控件网格赋值指南方案
  • Python爬虫实战:移动端逆向工具Fiddler经典案例
  • 24FIC 决赛 计算机部分
  • 【HFP】蓝牙语音通话控制深度解析:来电拒接与通话终止协议
  • 【前端】【业务场景】【面试】在前端开发中,如何优化 SVG(可缩放矢量图形)的性能,特别是在处理复杂图形和动画时
  • MCP实战-本地MCP Server+Cursor实践
  • AI日报 - 2025年04月25日
  • C语言-函数-1