C++ string类的实现

前言

C++ string 类提供了处理字符串的方式,现在来实现String类的实现方式

String.h文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
class String
{
private:
	int capacity;//内存大小
	char* str;
	int len;//字符串长度
	static int num_string;//记录字符串的数量
	bool _GrowMemory(int count, bool retainOgr = false);//动态扩容
public:
	String(const char* s);
	String(const String& s);
	String();
	~String();
	String& operator=(const String& s);
	String& operator=(const char* s);
	char& operator[](int i);
	void operator+=(const char& c);
	void operator+=(const String& s1);
	void operator+=(const char* s1);
	int Length();
	int Capacity();
	friend bool operator<(const String& s1, const String s2);
	friend bool operator>(const String& s1, const String s2);
	friend bool operator==(const String& s1, const String s2);
	friend String operator+(const String& s1, const String& s2);
	friend std::ostream& operator<<(std::ostream& os, const String& s);
	class iterator {
	private:
		char* pstr;
	public:
		iterator(char* p = nullptr);
		bool operator!=(const iterator& it);
		bool operator==(const iterator& it);
		iterator& operator++();
		iterator& operator++(int);
		iterator& operator--();
		iterator& operator--(int);
		char& operator*();
	};
	iterator begin() {
		return iterator(str);
	}
	iterator end() {
		return iterator(str + len);
	}
};

String.cpp 文件

构造函数和析构函数

int String::num_string = 0;//初始化静态字段
String::String(const char* s)
{
	capacity = 15;
	str = new char[capacity];
	len = strlen(s);
	_GrowMemory(len + 1);//+1,末尾放‘\0’
	strcpy(str, s);
	num_string++;
}

String::String(const String& s)
{
	capacity = 15;
	str = new char[capacity];
	len = s.len;
	_GrowMemory(len + 1);
	strcpy(str, s.str);
	num_string++;
}

String::String()
{
	capacity = 15;
	str = new char[capacity];
	len = 0;
	str[0] = '\0';
	num_string++;
}
String::~String()
{
	num_string--;
	delete[] str;
}

构造函数会在实例初始话的时候调用,下面的情况会调用构造函数和析构函数,默认会开辟15个字节的容量

String s1 = "dd";//==String s1("dd")
String s2 = s1;//==String s2(s1)
String s3;
String* s4 = new String("aa");
delete s4;//析构函数会在delete时调用

扩容

采用1.5倍扩容,可以降低new和delete的次数。

/// <summary>
/// 1.5倍数扩容
/// </summary>
/// <param name="count">字符串长度</param>
/// <param name="retainOgr">是否保留原内容</param>
/// <returns>返回是否扩容</returns>
bool String::_GrowMemory(int count, bool retainOgr)
{
	if (capacity >= count)return false;
	long temp;
	if (capacity < 16) {
		temp = capacity + 16;
	}
	else {
		temp = capacity + capacity / 2;
	}
	if (temp > INT32_MAX) {
		temp = INT32_MAX;
	}
	if (count > temp) {
		temp = count;
	}
	capacity = (int)temp;
	if (retainOgr) {
		char* temp = new char[capacity];
		strcpy(temp, str);
		delete[] str;
		str = temp;
	}
	else {
		delete[] str;
		str = new char[capacity];
	}
	return true;
}

运算符重载

=

String& String::operator=(const String& s)
{
	if (this == &s)return *this;
	len = s.len;
	_GrowMemory(len + 1);
	strcpy(str, s.str);
	return *this;
}

String& String::operator=(const char* s)
{
	len = strlen(s);
	_GrowMemory(len + 1);
	strcpy(str, s);
	return *this;
}

需要注意的是等于运算和构造函数的调用时机

string s5 = "1236";//构造String s5("1236")
s5 = "456789";//s5.operator=("456789")

[]

char& String::operator[](int i)
{
	return str[i];
}

+=

void String::operator+=(const char& c)
{
	len = len + 1;
	_GrowMemory(len + 1, true);
	str[len - 1] = c;
	str[len] = '\0';
}

void String::operator+=(const String& s1)
{
	len += s1.len;
	_GrowMemory(len + 1, true);
	strcat(str, s1.str);
}

void String::operator+=(const char* s1)
{
	len += strlen(s1);
	_GrowMemory(len + 1, true);
	strcat(str, s1);
}

>,<,==

bool operator<(const String& s1, const String s2)
{
	return strcmp(s1.str, s2.str) < 0;
}

bool operator>(const String& s1, const String s2)
{
	return strcmp(s1.str, s2.str) > 0;
}

bool operator==(const String& s1, const String s2)
{
	return strcmp(s1.str, s2.str) == 0;
}

+

String operator+(const String& s1, const String& s2)
{
	String ret;
	ret.len = s1.len + s2.len;
	ret._GrowMemory(ret.len + 1);
	strcpy(ret.str, s1.str);
	strcat(ret.str, s2.str);
	return ret;
}

重载<<

std::ostream& operator<<(std::ostream& os, const String& s)
{
	os << s.str;
	return os;
}

迭代器

typedef String::iterator iterator;
//迭代器构造函数
iterator::iterator(char* p)
{
	pstr = p;
}
//!=
bool iterator::operator!=(const iterator& it)
{
	return pstr != it.pstr;
}
//==
bool iterator::operator==(const iterator& it)
{
	return pstr == it.pstr;
}
//前置++
iterator& iterator::operator++()
{
	++pstr;
	return *this;
}
//后置++
iterator& iterator::operator++(int k)
{
	iterator temp = *this;
	pstr++;
	return temp;
}
//前置--
iterator& iterator::operator--()
{
	--pstr;
	return *this;
}
//后置--
iterator& iterator::operator--(int k)
{
	iterator temp = *this;
	pstr--;
	return temp;
}
//返回当前迭代值的引用
char& iterator::operator*()
{
	return *pstr;
}
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值