模拟string(一)详解

news2024/9/22 3:56:44

目录

  • string()构造函数无参初始化
    • 错误写法
    • 代码
  • string(const char* str)构造函数有参初始化
    • 错误写法
    • 代码
  • string(const char* str = "")合并无参和有参的构造函数代码
    • 错误写法
    • 代码
  • 拷贝构造函数
    • 浅拷贝
    • 深拷贝
      • 方法一string(const string& s)
      • 方法二string& operator=(const string& s)
        • 代码
  • ~string()析构函数
    • 代码

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录

string()构造函数无参初始化

错误写法

class string
{
public:
	string()
		:_str(nullptr)
		, _size(0)
		,_capacity(0)
	{ }
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

这里的错误是_str(nullptr),因为C++要对C语言进行兼容
而有一个函数是下面这样的,返回指针

		const char* c_str()
	{
		return _str;
	}

如果返回的是空指针,然后我们将他打印,就会出现问题
在这里插入图片描述
而我们用库里面的就不会出现问题
在这里插入图片描述

代码

	class string
	{
	public:
		string()
			:_str(new char[1])
			, _size(0)
			, _capacity(0)
		{ 
			_str[0] = '\0';
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}

在这里插入图片描述

string(const char* str)构造函数有参初始化

错误写法

指针初始化的时候不可以像下面这样

class string
{
public:
	string(const char* str)
		:_str (str)
	{

	}
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

因为在初始化的时候传入的指针可能会是下面这样的情况

string s1 ("A")

将常量字符串传入,导致在初始化后我们不能将str修改,并且不可以扩容
所以正确写法是自己开空间拷贝数据

class string
{
	string(const char* str)
		:_size(strlen(str))
		, _str(new char[_size+1])
		,_capacity(strlen(str))
	{
		strcpy(_str, str);

	}
	private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

这个顺序是不可以的,因为初始化列表的初始化顺序不是按实例化的顺序,而是按照声明的顺序初始化,这样就会导致_str在初始化的时候size为随机值,所以建议实例化顺序和声明顺序一致

代码

	class string
	{
	public:
		string(const char* str)
			:_str (new char[strlen(str)+1])
			,_size(strlen(str))
			,_capacity(strlen(str))
		{
			strcpy(_str, str);

		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};

这个代码可以优化,对于strlen我们可以少调用

class string
{
public:
	string(const char* str)
		:_size(strlen(str))
	{
		_capacity = _size;
		_str = new char[_capacity + 1];
		strcpy(_str, str);

	}
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

string(const char* str = “”)合并无参和有参的构造函数代码

错误写法

下面这个代码是想利用缺省参数实现无参和有参的合并

	class string
	{
	public:
		string(const char* str=nullptr)
			:_size(strlen(str))
		{
			_capacity = _size;
			_str = new char[_capacity + 1];
			strcpy(_str, str);

		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};

但是这样当我们传空指针的时候就会出现问题
在这里插入图片描述
而不传空指针就不会出现问题
在这里插入图片描述

这是因为strlen会对空指针进行解引用,strlen遇到\0才会停止,而空指针没有\0,所以就会崩溃
如果将缺省值改成string(const char* str=‘\0’)也会报错,因为\0是一个字符,将字符传给char *是不可以的
在这里插入图片描述

代码

所以缺省值应该是"\0"
在这里插入图片描述
当然我们也可以让缺省值写成"“,因为对于字符串来说,末尾都是以\0结尾,所以”\0"事实上有两个\0

	string(const char* str = "")
		:_size(strlen(str))
	{
		_capacity = _size;
		_str = new char[_capacity + 1];
		strcpy(_str, str);

	}

在这里插入图片描述

拷贝构造函数

浅拷贝

在没有实现拷贝构造函数的时候我们用的是编译器自动生成的拷贝构造函数,这时候会出现浅拷贝问题
在这里插入图片描述
通过调试我们可以看到s1和s2的地址是一样的
在这里插入图片描述
所以当结束后会先对s1析构,然后再对s2析构,但是因为s1和s2都指向同一块空间,导致这块空间析构两次,并且对s1进行修改数据的同时s2也会被修改

深拷贝

方法一string(const string& s)

根据上面的结果我们需要自己写一个深拷贝

	string(const string& s)
	{
		_str = new char[s._capacity + 1];
		strcpy(_str, s._str);
		_size = s._size;
		_capacity = s._capacity;
	}

其实就是s2开一块空间然后拷贝数据进去,然后s2指向这块开辟的空间
在这里插入图片描述

方法二string& operator=(const string& s)

代码
	string& operator=(const string& s)
	{
		char* tmp = new char[s._capacity + 1];
		strcpy(tmp, s._str);
		delete[]_str;
		_str = tmp;
		_size = s._size;
		_capacity = s._capacity;
		return *this;
	}

在这里插入图片描述
这样看起来没有什么问题

~string()析构函数

代码

	~string()
	{
		delete[] _str;
		_str = nullptr;
		_size = _capacity = 0;
	}

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

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

相关文章

Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: HadoopHDFSMapReduceHiveFlumeSqoopZookeeperHBase 正在 章节内容 上一节我们完成了: HBase …

linux环境安装mongoDB

一、安装单体mogodb 目标:在Linux中部署一个单机的MongoDB,作为生产环境下使用。 提示:和Windows下操作差不多。 步骤如下: (1)先到官网下载压缩包 mongod-linux-x86_64-4.0.10.tgz 。 (2&…

设计模式:真正的建造者模式

又臭又长的set方法 经常进行Java项目开发使用各类starter的你一定见过这种代码: public class SwaggerConfig {Beanpublic Docket api() {return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑光热集热单元的氢储能热电联供综合能源系统容量优化配置》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【Access、Trunk和Hybrid】

概述 Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口;Trunk类型的端口可以允许多个VLAN通过,可以接收和发送多个VLAN的报文,一般用于交换机之间连接的端口;Hybrid类型的端口可以允许多个VLAN通过&#xf…

Java中的迭代器(Iterator)

Java中的迭代器(Iterator) 1、 迭代器的基本方法2、 迭代器的使用示例3、注意事项4、克隆与序列化5、结论 💖The Begin💖点点关注,收藏不迷路💖 在Java中,迭代器(Iterator&#xff0…

1w字图文带你了解sqlmap,从0到1,WAF绕过,高级用法一文通透

前言 在信息安全领域,SQL注入攻击是一种极为常见且危害严重的安全漏洞。攻击者利用Web应用程序对SQL查询的不当处理,通过注入恶意SQL代码,从而绕过安全措施,非法访问或篡改数据库中的数据。随着网络安全威胁的日益严峻&#xff0…

在学习使用LabVIEW的过程中,需要注意哪些问题?

在学习使用LabVIEW的过程中,需要注意以下问题: 1. 基础知识 图形化编程思维: LabVIEW采用图形化编程方式,与传统的文本编程语言有很大不同,需要适应这种新的编程思维方式。数据流概念: 理解LabVIEW的核心数…

linux进程——概念理解与PCB

前言:本篇讲解Linux进程概念相关内容。 操作系统被称为计算机世界的哲学, 可以见得操作系统的知识并不好理解。 对于这篇进程概念的讲解, 博主认为, 如果没有一些前置知识的话,里面的有些概念并不好理解。 但是如果学习…

【机器学习实战】Datawhale夏令营2:深度学习回顾

#DataWhale夏令营 #ai夏令营 文章目录 1. 深度学习的定义1.1 深度学习&图神经网络1.2 机器学习和深度学习的关系 2. 深度学习的训练流程2.1 数学基础2.1.1 梯度下降法基本原理数学表达步骤学习率 α梯度下降的变体 2.1.2 神经网络与矩阵网络结构表示前向传播激活函数…

人工智能未来发展前景将会怎样?

当我们探讨人工智能未来的发展前景时,可以从多个角度来详细说明其可能的影响和趋势: 技术进步与应用扩展 1.深度学习与机器学习: 进一步优化和算法进展:深度学习已经取得了巨大成就,但仍面临挑战,如对小数…

AI伦理议题:从隐私保护到算法公平

文章目录 🍊1 人工智能兴起背后的伦理及道德风险1.1 算法偏见与歧视1.2 数据隐私侵权1.3 透明度受限1.4 决策失衡1.5 AI生成内容的危险性 🍊2 建构AIGC伦理观:实现人机共创的永续提升2.1 技术手段与伦理预防2.2 即时警告与紧急关停措施2.3 法…

Xcode进行真机测试时总是断连,如何解决?

嗨。大家好,我是兰若姐姐。最近我在用真机进行app自动化测试的时候,经常会遇到xcode和手机断连,每次断连之后需要重新连接,每次断开都会出现以下截图的报错 当这种情况出现时,之前执行的用例就相当于白执行了&#xff…

vue视频、图片自动轮播并伴随进度条

废话不多说直接上代 多余没用的部分自己看着删除 <template><div class"showImg"><el-carousel ref"carousel" trigger"hover" :autoplay"false" class"dimControl" :height"${(currenInnerWith*0.37…

JavaScript:移除元素

这是原题&#xff1a;给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以下操…

sourcrinlight 4.0 的使用技巧:如何在文件名后省略路径名

如图&#xff1a; 如果路径名很长&#xff0c;将显示不了几个文件名的&#xff0c;会造成一些不便。如何隐藏文件的路径名呢&#xff1f; 选中或取消这个按钮&#xff1a; 就可以了。要想再查看文件路径&#xff0c;鼠标放上去&#xff0c;就会显示了&#xff1a; 谢谢

数据融合工具(11)悬挂点自动检测和修复

一、需求背景 GIS数据通常需要满足拓扑规则&#xff0c;即点、线和面之间的拓扑关系应该正确。 悬挂点是指在地图数据中孤立存在的点&#xff0c;它们不与任何线或面的节点相连接。悬挂点通常是数据中的异常情况&#xff0c;可能是由于数字化或数据编辑错误而导致的。 下图以橙…

【关闭个人数据跨境传输】

现象 &#xff1a;WIN10更新补丁重启就有了这&#xff1b; 解决办法&#xff1a; 第一步&#xff1a;按shiftF10 第二步&#xff1a;按winR 第三步&#xff1a;输入taskmgr&#xff0c;回车 第四步&#xff1a;结束Microsoft账户进程&#xff0c;就可以进入桌面&#xff1…

Android中OkHttp3中超时时间概述

目录 前言connectTimeoutreadTimeoutwriteTimeoutcallTimeoutpingInterval拓展 前言 可以看到&#xff0c;使用还是很简单的。主要相关的有这五个参数&#xff0c;其中我们常用到是就是connectTimeout、readTimeout和writeTimeout。 再看上图&#xff0c;可以看到默认下connec…

matlab小白入门的基本使用

一.基本运算 加&#xff1a;a55 减&#xff1a;a5-2 立方&#xff1a;a2^3 乘&#xff1a;a2*3 ans默认变量名&#xff0c;应答最近依次操作运算结果eps浮点数的相对误差i,j虚数单位&#xff0c;定义-1inf代表无穷大NaN代表不定值&#xff08;不是数字&#xff09;pi圆周率…