stl中String类的实现
2023-03-14 22:51:25 时间
代码中写了详细的注释,这里就不展开对每个函数做说明解释了 string.h
#pragma once
#include<cstdlib>
#include<iostream>
using namespace std;
class String
{
private:
char* str;//指向动态数组的指针
int size;
void Error(const char* c)const;//错误信息报告
public:
//构造函数和析构函数
String(const char* c = "");//转换构造函数同时也是默认无参构造函数
String(const String& s);//复制构造函数
~String();
//访问方法:
//赋值运算符重载
String& operator=(const char* c);//转换赋值:类串=c串
String& operator=(const String& s);//转换赋值:类串=类串
//指定位置插入
String& Insert(int id, const String& s);//子串插入,插入到id下标之前
//指定位置,删除指定长度的子串
String& Erase(int id, int num);
//获取指定位置,指定长度的子串
String SubStr(int id, int num)const;
//串连接
String operator+(const String& s)const;//串连接:类串=类串+类串
String operator+(const char* c)const;//串连接:类串=类串+c串
friend String operator+(const char* c,const String& s);//串连接:类串=c串+类串
//串比较
bool operator==(const String& s);//串比较: 类串==类串
bool operator==(const char* c);//串比较:类串==c串
friend bool operator==(const char* c, const String& s);//串比较:c串==类串
//成员转换:特殊的operator类型转换函数
operator char* ()const; //将当前String对象转换为char*类型的对象,然后返回,即返回一个转换后的char* 对象
//下标运算符重载
char& operator[](int id); //非常量型下标运算符重载
const char& operator[](int id)const;//常量型下标运算符重载,注意这里的后置const不能少,因为只有后置const才能作为重载条件
//求串长
int Size(void)const { return size; }
//字符查找
int Find_First_Of(char ch, int id)const;
//子串查找
int Find_First_Of(const String& s, int id)const;
//输入输出运算符重载---做友元函数,因为左值要是输入输出符,而不是当前类对象
friend istream& operator>>(istream& istr, String& s);
friend ostream& operator<<(ostream& ostr, const String& s);
//串读取
int ReadString(istream& istr=cin, char delimiter='
');
};
string.cpp
#define _CRT_SECURE_NO_WARNINGS //如果关于strcpy等等函数报安全隐患,就加上这行代码,默认其为安全,注意:必须要置顶
#include"string.h"
#include<string.h>
//1.默认构造函数的实现--同时也是转换构造函数
//注意:如果声明的时候写了默认实参,那么实现的时候就不能再次写一遍,不然会报错
String::String(const char* c)
{
size = strlen(c);//strlen不包含 长度,sizeof包含
str = new char[size + 1];//str在动态创建时的长度为size+1,是因为要包含一个
if (!str)
Error("String: overflow!");
strcpy(str, c);
}
//2.错误信息报告
void String::Error(const char* c)const
{
cout << c << endl;
}
//3.赋值构造函数
String::String(const String& s)
{
size = s.size;
str = new char[size + 1];
if (!str)
Error("String: overflow!");
strcpy(str, s.str);
}
//4.成员赋值运算符重载
String& String::operator=(const char* c)
{
int len = strlen(c);
char* buf = str;
//如果长度一样,就不用重新开辟空间存储了
if (size != len)
{
str = new char[len + 1];
if(!str)
Error("String: overflow!");
delete[] buf;
size = len;
}
strcpy(str, c);
return *this;
}
String& String::operator=(const String& s)
{
if (size != s.size)
{
str = new char[s.size + 1];
if (!str)
Error("String: overflow!");
size = s.size;
}
strcpy(str, s);
return *this;
}
//5.成员转换函数---把当前string对象,转换为char*对象,并返回
String::operator char* ()const
{
char* c = new char[size + 1];
if(c==NULL)
Error("String: overflow!");
strcpy(c, str);
return c;
}
//6.串连接
//(1)类串与类串连接
String String::operator+(const String& s)const
{
String w;
int len = size + s.size;
delete[] w.str;
w.str = new char[len + 1];
if(!w.str)
Error("String: overflow!");
//一开始w是空的用拷贝,后来用连接字符串函数
strcpy(w.str, s.str);
strcat(w.str, str);
w.size = len;
return w;
}
//(2)类串与c串连接
String String::operator+(const char* c)const
{
String w;
int len = size + strlen(c);
delete[] w.str;
w.str = new char[len + 1];
if(!w.str)
Error("String: overflow!");
strcpy(w.str, c);
strcat(w.str, str);
w.size = len;
return w;
}
//(3)c串与类串连接
//注意:friend只能出现在友元函数的声明中,而不能出现在友元函数的实现中
String operator+(const char* c, const String& s)
{
String w;
int len = strlen(c) + s.size;
delete[] w.str;
if(!w.str)
s.Error("String: overflow!");//这里可以用Error私有函数是因为这里是友元函数
strcpy(w.str, c);
strcat(w.str, s.str);
w.size = len;
return w;
}
//7.关系运算符重载
bool String::operator==(const String& s)
{
return strcmp(str, s.str) == 0;
}
bool String::operator==(const char* c)
{
return strcmp(str, c) == 0;
}
bool operator==(const char* c, const String& s)
{
return strcmp(c, s.str) == 0;
}
//8.求子串--从下表id开始读取num个字符组成新的字符串,作为返回值
//步骤:
//(1):创建新的字符串s,并修改新串的字符串空间为num+1
//(2):将原串中的子串字符逐个赋给新串
String String::SubStr(int id, int num)const
{
int len = size;
int left = len - id,i;
if(id<0||id>len-1)
Error("id id illegal!");
if (num <= 0 || num > left)
Error("num is illegal!");
//步骤(1)
String s;
delete[] s.str;
s.str = new char[num + 1];
if (!s.str)
Error("overflow!");
s.size = num;
//步骤(2)
char* p = str + id;
char* p1 = s.str;
for (i = 1; i <= num; i++)
*p1++ = *p++;
*p1 = '