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

string模拟实现构造+析构

个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客

string模拟实现构造 

方案1(初始化列表的实现):

这一种方案是一种不完整方案,是不合适的方案,我是用来对比讲解使用的,所以可以看,可以不看,这里实现的无参数构造

//.h头文件
using namespace std;//突破域名
//这里我们采取namespace封装一下
namespace Test
{
	class string
	{
	public:
		//构造函数
		string();
        string(const char* str);
	private:
		//这里本质上就是字符串的增删查改,所以和数据结构是有点像的
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}

初始化列表格式进行初始化:
  1. 其实对于构造函数我们之前学过初始化列表和函数体的两种方式,所以我们到底在实际操作的时候,使用哪一种方式?这里采取初始化列表讲解,分析利弊。
  2. 初始化列表进行初始化,带参数构造的使用会存在一点问题,就是,我们需要先计算出字符串长度,然后才能开辟空间
  3. 初始化列表的构造,是按照私有成员变量的顺序进行初始化的,所以在后期代码维护,你的代码别人不注意就会很容易更改从而导致错误


初始化列表两种方式的代码:
  1. 不带参数

    这里创建是有一点小心机的,这里我们是_str(new char[]({'\0})->数组的形式创建空间,这里其实我们完全可以_str(new char{'\0}->不是数组形式创建空间,但是我们析构的时候,总不能再因为这个写两个析构函数吧,所以我这里直接就是使用创建多个空间的逻辑创建空间,也就是数组的形式创建空间
  2. 带参数


 

方案2(函数体和初始化列表的综合实现):

  1. 上面我们已经发现,纯粹采取初始化列表是可以实现的,但是是存在一些问题的,也就是我们需要改变私有变量的顺序
  2. 初始化列表的构造,是按照私有成员变量的顺序进行初始化的,所以在后期代码维护,你的代码别人不注意就会很容易更改从而导致错误
  3. 所以我们可以采取更加符合常规的一种写法

这里解释一下namespace,命名空间不仅可以单独给,还可以直接大规模的给,这样我们就可以不用在string.cpp实现的文件里面每次实现接口都需要 Test::string::接口。

//.h头文件
using namespace std;//突破域名
//这里我们采取namespace封装一下
namespace Test
{
	class string
	{
	public:
		//构造函数
        string(const char* str="");
	private:
		//这里本质上就是字符串的增删查改,所以和数据结构是有点像的
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}
//实现文件
#include"string.h"
namespace Test
{
	//构造函数(传参)
	string::string(const char* str)
		:_size(strlen(str))
	{
		_capacity = _size;
		_str = new char[_size + 1];
		strcpy(_str, str);
		//   目的地,来源
	}
}

代码的解释:

  1. 在头文件我们可以看见,string(const char* str="");,这里我们是不需要string(const char* str="\0");因为本身创建空间的时候就是会自带/0,没有必要继续加上/0
  2. 在实现上面,我们创建空间需要多创建一个空间,因为我们strlen是不计算\0的,所以我们需要_str = new char[_size + 1];从而在开辟空间的时候,多创建一个空间
  3. 最后我们只需要把字符拷贝到开辟好的空间,最后就可以
  4. 我们的测试我们会在实现析构之后一起进行测试,这里就不单独测试了

注意事项:

  1. 之前我们说过,在vs编译器下,cpp编译下,一些C语言的语法结构是需要写一行代码的,不然会导致报错
  2. #define  _CRT_SECURE_NO_WARNINGS 1//这一行代码,这是编译器的行为,编译器也会提醒你加上,这里我说明一下,不是语法结构的问题,是编译器认为这里有危险,加上这一行强制使用就可以。

string模拟实现析构

析构函数的实现是比较简单的,这里只需要直接析构就可以,因为我们创建空间的时候我们都是采取数组的形式创建的空间,所以我们析构的时候,我们直接数组的形式析构就可以

//头文件
#define  _CRT_SECURE_NO_WARNINGS 1
#pragma once
using namespace std;//突破域名
//这里我们采取namespace封装一下
namespace Test
{
	class string
	{
	public:
		//构造函数
		string(const char* str="");

		//析构函数
		~string();

	private:
		//这里本质上就是字符串的增删查改,所以和数据结构是有点像的
		char* _str;
		size_t _size;
		size_t _capacity;
	};
}
//实现文件
#include"string.h"
 
namespace Test
{
	构造函数(不传参)
	//string::string()
	//	:_str(new char[1] {'\0'})
	//	, _size(0)
	//	, _capacity(0)
	//{}
	// _size指的是实际的个数
	// _capacity指的是空间,空间的使用
	//构造函数(传参)
	string::string(const char* str)
		:_size(strlen(str))
	{
		_capacity = _size;
		_str = new char[_size + 1];
		strcpy(_str, str);
		//   目的地,来源
	}
	//析构函数
	string::~string()
	{
		delete[] _str;
		_str = nullptr;
		_size = 0;
		_capacity = 0;
	}
}

代码讲解:

  1. 首先我们析构_str字符串,这里我们采取析构数组的方式进行析构
  2. 让字符串指向空,C++的空和C语言的空是不一样的
  3. 最后把_size,_capacity,都归0
  4. 比较简单,这里不做过多赘述,这里的核心是提高测试调试的使用能力

代码测试:

  1. 在构造函数里面我们没有测试,因为一方面我们知道我们写的代码很简单不会报错,一方面我们的析构函数没有实现,其实不实现也可以测试,只是作者有点懒,想起来需要测试的时候,已经写到这里了。
  2. 构造函数的测试
  3. 析构函数的测试

注意事项:

  1. 下面我们讲解代码的时候,除非头文件有缺省参数参数,上代码的时候,我会只是实现这个函数接口的实现,但是需要头文件的时候,我会进行讲解这个头文件

http://www.kler.cn/a/382511.html

相关文章:

  • 达梦数据守护集群_动态增加实时备库
  • Android 面试题汇总
  • 用ChatGPT提高工作效率,轻松搞定每天任务!
  • 影响神经网络速度的因素- FLOPs、MAC、并行度以及计算平台
  • 基于STM32单片机太阳能充电循迹避障小车
  • AAA 数据库事务隔离级别及死锁
  • Java学习Day60:微服务总结!(有经处无火,无火处无经)
  • 栈的算法题 —— 有效的括号(LeetCode)
  • Java | Leetcode Java题解之第539题最小时间差
  • Python 自动化运维:安全与合规最佳实践
  • go 包管理
  • 进程和线程概念
  • Transformer究竟是什么?预训练又指什么?BERT
  • 查看 Active NameNode 的服务 ID
  • TryHackMe | Active Directory Basics
  • 2024中国自动化大会(CAC2024)“智慧化工及复合人才培养”平行会议圆满落幕
  • 50. Pow(x, n)
  • android——jetpack startup初始化框架
  • 区别:矩阵合同和矩阵酉相似
  • Android15音频进阶之Cuttlefish搭建音频开发环境(九十二)
  • 了解数据库并发产生的问题
  • Claude发布桌面客户端!新功能支持分析100页PDF的图像!
  • 知识课堂——高匿ip在不同业务中的重要作用
  • 蓝桥杯真题——乐乐的序列和(C语言)
  • 每日算法一练:剑指offer——字符串篇(2)
  • Lua 怎么解决闭包内存泄漏问题