首页 > 其他分享 >string接口的模拟实现

string接口的模拟实现

时间:2024-11-22 18:19:48浏览次数:3  
标签:capacity string 接口 char str operator 模拟 size

文章目录

一. string底层逻辑

(1)为了和库里面的string类区分开,我们可以使用命名空间(hou)。之前学习的命名空间就有了价值。
(2)在类里面的都是内联函数在这里插入图片描述
(3)对于比较短小的函数,直接在类里面写就行。函数大一点,将声明和定义分开。

  1. 成员变量
#include<stdio.h>
#include<string>
#include<iostream>
namespace hou
{
	class string
	{
	private:
		char* _str;    //char类型数据数组的地址
		size_t _size;  //有效元素个数
		size_t _capacity; //空间大小
	};
}
  1. 成员函数
    任何一个类都从构造函数开始(无参/有参)

无参的话,将三个成员变量初始化为什么呢?都初始化为空吗?

这样是不可以的。
记得:const char*比较特殊,cout它不会打印出地址,它自动识别类型,会以为打印字符串(字符串的打印规则是遇到‘\0’才会终止),而我们的_str是空指针,将空指针解引用,肯定是错误的(本质是空指针问题)
在这里插入图片描述



---------------在这里插入图片描述
所以,不能将char*初始化为空。里面起码要放一个'\0'
在这里插入图片描述

namespace hou
{
	class string
	{
	public:
		//任何一个类都从构造函数开始
		string()//先写一个无参的构造函数
			:_str(new char[1]{'\0'})
			,_size(0)
			,_capacity(0)
		{}
		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = 0;
			_capacity = 0;
		}
		const char* c_str()const
		{
			return _str;
		}
	private:
		char* _str;    //char类型数据数组的地址
		size_t _size;  //有效元素个数
		size_t _capacity; //空间大小
	};
}

刚刚写了无参的构造函数,接下来写一个有参的构造函数
注意点:

  1. strlen计算长度时,不包括'\0'
  2. strlen是在运行时计算的,size是编译时计算的
  3. 在初始化列表里写,它的初始化顺序是按照声明的顺序来的
    在这里插入图片描述
    之前我们说过,尽可能使用初始化列表,但是strlen是在运行时计算的,要计算3次,效率低。这样子的话,我们可以将strlen先计算出来,之后用。但记住,初始化列表的顺序是按照声明的顺序。

演示声明和定义分开

当我们想把声明写在.h里面,定义写在.cpp里面的时候
在这里插入图片描述
这样写会报错,所以我们需要在string.cpp里(1)写上类域(2)再写一下命名空间
一个命名空间是可以写多个的,多个文件的同一个命名空间会被合并为(认为)一个命名空间的
在这里插入图片描述




在这里插入图片描述

已经声明和定义了,还有一个需要注意的内容是,缺省值只能在声明的时候给(定义那里不可以写缺省值)。但是char* _str的缺省值不可以是nullptr,可以给一个'\0'或者直接“”(字符串默认后面会加'\0'的)

二. size()

  • 对象.size()就是为了得到对象的大小(即对象的有效元素个数)

如果声明和定义分开写了,同时这个函数有返回值,那string::加到哪里呢?

在这里插入图片描述

三. operator[]

string.cpp里面的内容

char& string::operator[](size_t i)
{
	return _str[i];
}

四. 迭代器

string的迭代器(string的物理结构是数组)

using iterator = char*;
//typedef char* iterator;

迭代器还需要配合begin()end()(begin()就是返回开始位置的迭代器)

using iterator = char*;
iterator string::begin()
{
	return _str;
}
iterator string::end()
{
	return _str+_size;
}

在这里插入图片描述

范围for的底层是迭代器(支持迭代器则支持范围for)

在这里插入图片描述

四. const迭代器

在这里插入图片描述

五. 预留空间(reserve)

本质就是扩容,但是这种提高了效率,原本需要2倍2倍的扩,但是当你知道需要多大的空间时,就可以一次性扩容好。

在这里插入图片描述

  1. reserve一般不缩容,我们需要先判断一下,想扩容的大小n是否比_capacity大
  2. 开空间的时候永远要多开一个,因为’\0‘是不计入_capacity
	void string:: reserve(size_t n)
	{
		if (n > _capacity)
		{
			char* tmp=new char[n+1];
			strcpy(tmp, _str);
			delete[]_str;
			_str = tmp;
			_capacity = n; //'\0'不计入空间大小
		}
	}

六. 尾插一个字符push_back

void string::push_back(char ch)
{
	//先判断空间大小是否足够
	if (_size = _capacity)
	{
		//不够的话进入if语句进行扩容
		reserve(_capacity = 0 ? 4 : 2 * _capacity);
	}
	_str[_size] = ch;
	_size++;
}

七. 尾插一个字符串append

	void string::append(const char* str)
	{
		size_t len = strlen(str);
		size_t newcapacity = 2 * _capacity < _size + len ? _size + len : 2 * _capacity;
		reserve(newcapacity);
		//开好空间之后,插入字符串
		strcpy(_str+_size, str);//直接复制(第一个参数是复制到哪里(位置),第二个是被复制的串)
		_size += len;
	}

八. operator+=

string& string:: operator+=(char ch)
{
	push_back(ch);
	return *this;
}

九. operator+=


string& string:: operator+=(const char* str)
{
	append(str);
	return *this;
}

标签:capacity,string,接口,char,str,operator,模拟,size
From: https://blog.csdn.net/2402_83250773/article/details/143955162

相关文章

  • NOIP 模拟赛:2024-11-19
    T1:对两个字符串\(a,b\),分别选择\(a\)的一个前缀和\(b\)的一个后缀(均允许为空或等于原串),并拼接形成一个新的字符串。求共有多少种可能得到的本质不同的拼接串。结论题。对于一个\(a\)的前缀\(a[1\simi]\),有\(m+1-cntb[a[i]]\)个新的串。证明:T2:对一个\(n\)个点\(m\)条......
  • 11.22 模拟赛
    前言大唐胜屎\(T1\)镜的绮想水签CODE#include<bits/stdc++.h>typedeflonglongll;usingnamespacestd;constintN=5e3+100;constintM=4e6+100;intn,m;structPoi{ intx,y;}a[N],b[N];intnum[M];signedmain(){ autoRet1=f......
  • 【11.21模拟赛T4】 —神奇数论之构造exgcd
    给出正整数\(a,b,c,m\),其中\(a,b,c\)两两互质,\(T\)组数据,任意一个三元组\((x,y,z)\)满足:\[(x^a+y^b)\mod\m\equiv(z^c)\mod\m,\x,y,z\in(0,m)\capZ\]\(a,b,c\le10^9,3\lem\le10^9,T\le10^5\)首先他有一个部分分:\(m\)为\(2\)的整次幂这时我们不难发现......
  • 6.STM32之通信接口《精讲》之USART通信(PC串口与OLED交互)---多字节数据收发(数据包的模
    本节将串口收发HEX数据包(发送数据包很简单,主要还是关注一下如何接收数据包)在这里给大家介绍一下状态机的思想状态机模式(StateMachinePatern)是一种用于描述对象的行为软件设计模式,属于行为型设计模式。在状态机模式中,对象的行为取决于其内部状态,并且在不同的状态下,对象可......
  • golang如何提取接口类型的实际类型
    目录类型断言的基本用法处理多种可能的类型获取接口的实际类型总结在Go语言中,如果你想从接口类型的值中提取实际类型,可以使用类型断言(typeassertion)。类型断言允许你检查接口变量的实际类型并将其转换为该类型。类型断言的基本用法假设你有一个接口类型的变量i,你可以使用......
  • String、StringBuilder 和 StringBuffer 的区别
    Shiro视频地址:https://www.bilibili.com/video/BV1YVUmYJEPi/?spm_id_from=333.999.0.0&vd_source=14d27ec13a4737c281b7c79463687112SpringBoot视频地址:https://www.bilibili.com/video/BV1nkmRYSErk/?spm_id_from=333.999.0.0&vd_source=14d27ec13a4737c281b7c7946368......
  • C++:模拟实现unordered_map和unordered_set
    目录一.unordered_set和unordered_set二.哈希表的改造三.整体代码1.MyUnorderedMap.h2.MyUnorderedSet.h3.HashTable.h4.Hash.cpp一.unordered_set和unordered_setunordered_set和unordered_map的实现通过调用哈希表即可#pragmaonce#include"HashTable.h"using......
  • 统计项目中所有Mapper接口的数量
    前言统计某包下边所有mapper接口下的所有方法数量代码importjava.io.File;importjava.io.IOException;importjava.lang.reflect.Method;importjava.net.URL;importjava.util.Enumeration;/***@authorbaicaizhi*/publicclassTest{publicstatic......
  • 模拟计算板卡设计方案:429-基于XC7Z035+ADS5474的2路400Msps AD 光电脉冲采集处理卡
    基于XC7Z035+ADS5474的2路400MspsAD光电脉冲采集处理卡一、板卡概述    板卡基于高速400M采样AD和ZYNQFPGA构建嵌入式的模拟计算板卡,可用于光电脉冲采集。板卡使用工业级芯片。    二、主要技术指标使用 Zynq-7000 SoC  XC7Z035对嵌入式应用进行快速原......
  • [XYD20241118] NOIP 模拟赛
    [XYD20241118]NOIP模拟赛目录[XYD20241118]NOIP模拟赛因子之和DescriptionSolution小w与数字游戏DescriptionSolution\(30\%\)做法FinalSolution树论DescriptionSolution\(50\%\)做法\(70\%\)做法FinalSolutionProof引理1引理2基础数论练习题DescriptionSolution\(1......