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

16.C++STL 3(string类的模拟,深浅拷贝问题)

⭐本篇重点:string类的模拟,自己实现一个简单的string类

⭐本篇代码:c++学习/05.string类的学习 · 橘子真甜/c++-learning-of-yzc - 码云 - 开源中国 (gitee.com)

目录

一. 经典string类的模拟

1.1 深浅拷贝问题

 1.2 使用深拷贝完成经典string类的模拟

a size函数

b 拷贝构造函数

 c 赋值运算符重载

d operator[]重载

二. 现代写法的string类模拟

2.1 拷贝构造函数

 2.2 赋值运算符重载

三. 下篇文章:STL中vector的使用 


一. 经典string类的模拟

        实现一个简单的string类,主要是实现string类的构造函数,析构函数,拷贝构造函数,赋值运算符重载。这个过程需要我们首先理解深浅拷贝的问题。

1.1 深浅拷贝问题

        浅拷贝问题:如果我们初始化一个对象的时候,只是简单的将另一个对象的值赋值给这个对象。比如我们在堆上申请的空间。当我们销毁这两个对象的时候,由于它们指向同一个空间,这个空间就会被销毁两次。程序就会崩溃

测试代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;namespace yzc
{class string{public:string(const char* str = ""):_str(new char[strlen(str) + 1]){cout << "调用构造函数" << endl;strcpy(_str, str);}//拷贝构造string(const string& str){*this = str;}~string(){cout << "调用析构函数" << endl;delete[] _str;}void print(){cout << _str << endl;}private:char* _str;};
}int main()
{yzc::string s1 = "123456";yzc::string s2 = "abcdef";s1.print();s2.print();return 0;
}

没有调用拷贝构造函数,可以正常输出。

运行结果如下:

如果我们使用拷贝构造函数

int main()
{yzc::string s1 = "123456";yzc::string s2(s1);return 0;
}

分析代码可知,由于浅拷贝问题。输出一次调用构造函数和两次析构函数后程序崩溃

只有使用深拷贝,我们在拷贝构造函数里面重新申请一份空间,然后重新全部复制才行。 

 1.2 使用深拷贝完成经典string类的模拟

a size函数

        为了完成深拷贝,我们需要定义一个size函数用于求_str的长度。加上const,因为函数内部并不会更改任何值

		int size()const{return strlen(_str);}

b 拷贝构造函数

与构造函数类似,我们重新开辟一份空间,然后使用strcpy进行拷贝

​//拷贝构造,使用深拷贝完成拷贝string(const string& s):_str(new char[s.size()]){strcpy(_str, s._str);}

测试代码: 

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;namespace yzc
{class string{public:string(const char* str = ""):_str(new char[strlen(str) + 1])	//由于C语言字符串后面都带'\0',需要加上1{strcpy(_str, str);}拷贝构造//string(const string& str)//{//	*this = str;//}//拷贝构造,使用深拷贝完成拷贝string(const string& s):_str(new char[s.size() + 1])    //一定要注意要加1,否则会越界访问{strcpy(_str, s._str);}~string(){delete[] _str;_str = nullptr;}int size()const{return strlen(_str);}void print(){cout << _str << endl;}private:char* _str;};
}int main()
{yzc::string s1 = "123456";yzc::string s2(s1);s1.print();s2.print();return 0;
}

测试结果 

 c 赋值运算符重载

与拷贝构造函数一样,要注意深浅拷贝的问题

		//赋值运算符重载string& operator=(const string& s){if (this != &s)//地址不同才进行赋值{delete[] _str; //释放原地址空间,防止内存泄漏//定义中间变量tmp用于拷贝char* tmp = new char[s.size() + 1]; //注意要 + 1strcpy(tmp, s._str);_str = tmp;}return *this; //返回当前对象,为了支持 a = b = c}

 测试:主函数代码如下

int main()
{yzc::string s1 = "123456";yzc::string s2 = "abcdef";yzc::string s3 = s1;yzc::string s4;s4 = s2;s3.print();s4.print();return 0;
}

测试结果:

d operator[]重载

我们还能重载[]这个操作符,方便我们遍历整个字符串

直接输入i,返回_str[i]即可(注意const) 

		char& operator[](size_t i){assert(i < size());return _str[i];}const char& operator[](size_t i)const{assert(i < size());return _str[i];}

测试代码:

int main()
{yzc::string s1 = "159753468244";for (int i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;return 0;
}

运行结果:

二. 现代写法的string类模拟

2.1 拷贝构造函数

         为了提高代码的复用,我们在拷贝构造函数中使用构造函数去构造一个对象,然后交换当前对象和这个对象。

代码如下:

		//现代版写法string(const string& s):_str(nullptr){string strTmp(s._str); //使用构造函数将s._str构造一个tmpswap(_str, strTmp._str);//交换_str和tmp}

交换后,strTmp由于是局部变量就直接被销毁了! 而我们创建的对象被保留

 2.2 赋值运算符重载

我们使用传值方法传参,交换_str后我们成功创建的对象。且不会影响传入的对象

//现代版写法string& operator=(string s) //不使用引用传参,而是传值{swap(_str, s._str);return *this;}

测试代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
using namespace std;namespace yzc
{class string{public:string(const char* str = ""):_str(new char[strlen(str) + 1])	//由于C语言字符串后面都带'\0',需要加上1{strcpy(_str, str);}拷贝构造,使用深拷贝完成拷贝//string(const string& s)//	:_str(new char[s.size() + 1]) //注意要加1//{//	strcpy(_str, s._str);//}//现代版写法string(const string& s):_str(nullptr){string strTmp(s._str); //使用构造函数将s._str构造一个tmpswap(_str, strTmp._str);//交换_str和tmp}赋值运算符重载//string& operator=(const string& s)//{//	if (this != &s)//地址不同才进行赋值//	{//		delete[] _str; //释放原地址空间,防止内存泄漏//		//定义中间变量tmp用于拷贝//		char* tmp = new char[s.size() + 1];//		strcpy(tmp, s._str);//		_str = tmp;//		//	}//	return *this; //返回当前对象,为了支持 a = b = c//}//现代版写法string& operator=(string s) //不使用引用传参,而是传值{swap(_str, s._str);return *this;}~string(){delete[] _str;_str = nullptr;}size_t size()const{return strlen(_str);}void print(){cout << _str << endl;}private:char* _str;};
}int main()
{yzc::string s1 = "123456";yzc::string s2(s1);yzc::string s3 = s1;s1.print();s2.print();s3.print();return 0;
}

运行结果:

三. 下篇文章:STL中vector的使用 

相关文章:

16.C++STL 3(string类的模拟,深浅拷贝问题)

⭐本篇重点&#xff1a;string类的模拟&#xff0c;自己实现一个简单的string类 ⭐本篇代码&#xff1a;c学习/05.string类的学习 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. 经典string类的模拟 1.1 深浅拷贝问题 1.2 使用深拷贝完成经典string类的…...

神经网络10-Temporal Fusion Transformer (TFT)

Temporal Fusion Transformer (TFT) 是一种专为时序数据建模而设计的深度学习模型&#xff0c;它结合了Transformer架构和其他技术&#xff0c;旨在有效地处理和预测时序数据中的复杂模式。TFT 于 2020 年由 Google Research 提出&#xff0c;旨在解决传统模型在时序预测中的一…...

“iOS profile文件与私钥证书文件不匹配”总结打ipa包出现的问题

目录 文件和证书未加载或特殊字符问题 证书过期或Profile文件错误 确认开发者证书和私钥是否匹配 创建证书选择错误问题 申请苹果 AppId时勾选服务不全问题 ​总结 在上线ios平台的时候&#xff0c;在Hbuilder中打包遇见了问题&#xff0c;生成ipa文件时候&#xff0c;一…...

《图像梯度与常见算子全解析:原理、用法及效果展示》

简介:本文深入探讨图像梯度相关知识&#xff0c;详细介绍图像梯度是像素灰度值在不同方向的变化速度&#xff0c;并以 “pig.JPG” 图像为例&#xff0c;通过代码展示如何选取图像部分区域并分析其像素值以论证图像梯度与边缘信息的关联。接着全面阐述了 Sobel 算子&#xff0c…...

【c++篇】:探索c++中的std::string类--掌握字符串处理的精髓

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨文章所属专栏&#xff1a;c篇–CSDN博客 文章目录 前言一.std::string对象的创建二.std::string对象的访问三.std::str…...

LlamaIndex ollama 搭建本地RAG应用,建立本地知识库

目录 简介安装前的准备下载ollama创建llamaindex conda环境&#xff0c;为后面编码作准备 环境变量迁移ollama到其他盘运行ollama方式一方式二禁止ollama开机自启动运行第一个模型 Chatbox聊天下载Chatbox配置ollama地址和模型验证 建立自身特定知识数据搭配大语言模型创建项目…...

draggable的el-dialog实现对话框标题可以选择

请看图 这个对话框使用了el-dialog并且draggable属性设置成了true&#xff0c;所以标题栏这里就可以拖动&#xff0c;现在用户想选中标题栏的文本进而复制。我看到这个需求头都大了。 我能想到的方案有三个&#xff1a;1. 取消draggable为true 2. 标题文案后面加一个复制按钮 …...

2024年Android面试总结

2024年Android面试总结 1.动画类型有哪些&#xff1f;插值器原理&#xff1f; 2.StringBuffer和StringBuilder区别&#xff1f; 3.jvm内存模型&#xff1f; 4.线程池7大核心参数及原理&#xff1f; 5.Android多进程通信方式有哪些&#xff1f;各自的优缺点&#xff1f; 6…...

树莓派3:64位系统串口(UART)使用问题的解决方法

前言 当我们要使用串口进行zigbee的短距离通信时,发现无法使用串口. 原因 树莓派3bCPU内部有两个串口,一个硬件串口(就是我们平时使用的UART),还有一个迷你串口(mini-uart),在老版本的树莓派中把硬件串口分配在GPIO上,可以单独使用.但是在新的树莓派中官方把硬件串口给了蓝牙…...

SemiDrive E3 硬件设计系列---唤醒电路设计

一、前言 E3 系列芯片是芯驰半导体高功能安全的车规级 MCU&#xff0c;对于 MCU 的硬件设计部分&#xff0c;本系列将会分模块进行讲解&#xff0c;旨在介绍 E3 系列芯片在硬件设计方面的注意事项与经验&#xff0c;本文主要讲解 E3 硬件设计中唤醒电路部分的设计。 二、RTC 模…...

淘宝接口高并发采集核心要点解读,开启电商数据智能应用新纪元

一、引言 在电商蓬勃发展的今天&#xff0c;淘宝作为全球知名的电商巨头&#xff0c;其平台上的数据犹如一座蕴藏无限价值的宝藏。准确且高效地采集淘宝接口数据&#xff0c;并通过高并发技术实现大规模数据获取&#xff0c;对于电商企业的精准营销、市场趋势分析、竞品监测以及…...

C#里怎么样快速使用LINQ实现查询?

C#里怎么样快速使用LINQ实现查询? 在C#里使用LINQ,是一个方便的功能, 不过,要学会使用这部分的功能,需要比较多的学习时间,否则,使用起就比较难。 因为它的表现方式,与编程语言通用的功能,还是差别比较大。 当数据量比较小,没有特定的顺序时,使用LINQ访问会比较好…...

2024新版微软edge浏览器输入百度网址时自动补全tn=68018901……小尾巴的解决

以前一直是Windows11 21h2版本&#xff0c;浏览器内输入baidu不会自动补全tnxx的百度推广小尾巴。然后前几天在BIOS内开启了tpm2.0&#xff0c;升级Windows11到了24h2版本。 发现在edge浏览器内只要输入b&#xff0c;就会自动补全为baidu.com?tnXXX的这么一个百度推广形式。开…...

uni-app打包H5自定义微信分享

1、配置分享信息 修改uni-app的index.html,添加Open Graph(OG)标签来配置分享信息。 <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="description" content="标题"/>…...

大模型专栏--大模型应用场景

紧接着第一篇&#xff0c;什么是大模型&#xff0c;这篇文章讨论一下大模型的应用场景和应用方式有哪些&#xff1f; 基础使用 随着 GPT 的出现&#xff0c;AI 大模型已经越来越多得出现在日常生活和学术研究&#xff0c;工作中。 按照使用方向有以下几种&#xff1a; 自然语…...

骑砍2霸主MOD开发(29)-顶点动画

一.定制化顶点动画(MorphAnimation) 定制化顶点动画用于人物Agent的面部表情. 1.创建MorphAnimation对应静态资源morph_animation.tpac 2.Agent设置对应MorphAnimation [EngineMethod("set_agent_facial_animation", false)] void SetAgentFacialAnimation(UIntPtr …...

-Dspring.profiles.active=dev与--spring.profiles.active=dev的区别

在Spring Boot应用程序中&#xff0c;-Dspring.profiles.activedev和--spring.profiles.activedev都用于指定要激活的Spring配置文件&#xff08;profile&#xff09;&#xff0c;但它们在不同的环境中使用&#xff0c;并且有不同的作用域。 -Dspring.profiles.activedev&#…...

面向对象高级(2)单例设计对象与代码块

面向对象高级&#xff08;2&#xff09; 单例设计模式、main方法与代码块 引言&#xff1b; 设计模式&#xff1a;特定环境下特定问题的处理方法。可理解为一种经典的可以参照的模板。单例设计模式则是只存在单个对象实例、且只有一种方法获取对象实例的一种设计模式。 单例设…...

47小型项目的规划与实施

每天五分钟学Linux | 第四十七课&#xff1a;小型项目的规划与实施 大家好&#xff01;欢迎再次来到我们的“每天五分钟学Linux”系列教程。在前面的课程中&#xff0c;我们学习了并发编程的知识&#xff0c;包括如何管理和使用进程与线程。今天&#xff0c;我们将探讨如何规划…...

堤防安全监测系统方案

一、背景情况 堤防是开发利用水资源和防治水灾害的重要工程措施之一&#xff0c;对防洪、供水、生态、发电、航运等至关重要。我国现有堤防9.8万多座&#xff0c;其中大中型堤防4700多座、小型堤防9.4万座&#xff0c;80%以上修建于上世纪50至70年代。由于堤防管护力量薄弱&am…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...