引言:本篇文章主要实现一个自定义字符串类string,包括了字符串的基本操作,如拷贝构造、赋值、添加、删除、查找等,还实现了迭代器,支持基本的 STL 算法。
1. 构造函数:
- 默认构造函数
- 从C字符串构造
- 拷贝构造函数
2. 析构函数
- 在析构函数中释放内存
3. 访问和修改元素函数:
- c_str() 返回C字符串
- size() 返回字符串大小
- capacity() 返回容量
- operator[] 访问单个字符
4 查找子串
- find() 从某个位置查找字串
5. 迭代器相关:
- begin() 返回开始迭代器
- end() 返回结束迭代器
6. 修改容量相关:
- push_back() 尾部插入字符
- append() 尾部插入字符串
- reserve() 预留空间
- resize() 重新设置字串的大小
7. 重载运算符:
- 实现+=操作符的重载,用于字符串拼接
- 实现=操作符的重载,用于字符串赋值
- 重载输出运算符 << 打印字符串
8. insert()
- 插入字符
9. erase()
- 删除从某个位置后面某长度的字符
10. swap()
- 交换两个字符串的值
#include
#include
#include
using std::cout;
using std::endl;
using std::cin;
class string{
public:
typedef char* iterator; // 定义迭代器类型
// 构造函数
string(const char* str ="");
string(const string& str);
// 析构函数
~string();
// 返回C风格字符串
char* c_str();
// 返回字符串长度
int size()const;
// 返回容量
int capacity()const;
// 字符访问运算符
char& operator[](int n);
const char& operator[](int n)const;
// 获取首尾迭代器
iterator begin();
iterator end();
// 在尾部插入字符
void push_back(char c);
// 连接字符串
string& append(const string& str);
string& append(const char* s);
// 扩容
void reserve(size_t n = 0);
// +=运算符重载
string& operator+=(const char c);
string& operator+=(const char* s);
string& operator+=(const string& str);
// 在pos位置插入字符串
string& insert (size_t pos, const char* s);
string& insert (size_t pos, const string& str);
// 在迭代器p位置插入字符
iterator insert (iterator p, char c);
// 查找子串
size_t find (const char* s, size_t pos = 0) const;
size_t find (const string* str,size_t pos = 0) const;
// 删除字符串的一部分
string& erase (size_t pos = 0, size_t len = npos);
// 赋值运算符重载
string& operator= (const string& str);
string& operator= (const char* s);
string& operator= (char c);
// 改变字符串长度
void resize (size_t n, char c='\0');
// 交换两个字符串内容
void swap(string& str);
private:
char* _str; // 用于保存字符串
int _size; // 字符串长度
int _capacity; // 容量
static const size_t npos = -1; // 表示找不到
};
// 输出运算符重载
std::ostream& operator<< (std::ostream& out,const string& s);
#include "my_string.h"
string::string(const char* str){
_str = new char[strlen(str)+1];
strcpy(_str,str);
_size = strlen(str);
_capacity = _size;
}
string::string(const string& str)
:_str(nullptr)
{
if(&str != this){
char* tmp = new char[str._size+1];
strcpy(tmp,str._str);
delete []_str;
_str = tmp;
_size = str._size;
_capacity = _size;
}
}
string::~string(){
delete []_str;
_str = nullptr;
_size = 0;
_capacity = 0;
}
char* string::c_str(){
return _str;
}
int string::size()const{
return _size;
}
int string::capacity()const{
return _capacity;
}
char& string::operator[](int n){
assert(n<_size);
return *(_str+n);
}
const char& string::operator[](int n)const{
assert(n<_size);
return *(_str+n);
}
string::iterator string::begin(){
return _str;
}
string::iterator string::end(){
return _str+_size;
}
void string::push_back(char c){
if(_size == _capacity){//需要扩容
_capacity++;
char* tmp = new char[_capacity+1];
strcpy(tmp,_str);
delete [] _str;
_str = tmp;
}
_str[_size] = c;//放入元素
_size++;
_str[_size] = '\0';//插入元素后放一个\0
}
string& string::append(const string& str){
if(_size + str.size() > _capacity){//需要扩容
reserve(str.size()+_size);//调用reserve,复用
}
for(int i = 0;i _capacity){
reserve(s_size + _size);
}
strcpy(_str + _size,s);
_size += s_size;
return *this;
}
void string::reserve(size_t n ){
char *tmp = new char[n+1];
strcpy(tmp,_str);
delete [] _str;
_str = tmp;
_capacity = n;
}
string& string::operator+=(const char c){
push_back(c);
return *this;
}
string& string::operator+=(const char* s){
append(s);
return *this;
}
string& string::operator+=(const string& str){
append(str);
return *this;
}
string::iterator string::insert(string::iterator p,char c){
assert( p <= end());
int pos = p - begin();
if(_size+1>_capacity){//扩容
reserve(_size+1);
}
p = _str + pos;
for(string::iterator it = end()-1;it >= p;it--){//往后面移
*(it+1) = *it;
}
*p = c;
_size ++;
return p;
}
string& string::insert(size_t pos,const char* s){
assert(pos<=_size);
int s_len = strlen(s);
if(s_len+_size>_capacity){
reserve(_size+s_len);
}
for(int i = _size;i >= (int)pos;i--){
_str[i+s_len] = _str[i];
}
for(int i = 0;i_str;
return find(s,pos);//复用
}
string& string::erase(size_t pos,size_t len){
assert(pos<_size);//不能在'\0'位置之后的删除
if(len>=(size_t)_size-pos){
_size = pos;
_str[_size] = '\0';
}else{
for(int i = pos;i<=_size-(int)len;i++){
_str[i] = _str[i+len];
}
_size = _size - len;
}
return *this;
}
string& string::operator=(const char* s){
assert(s);
int s_len = strlen(s);
reserve(s_len);
strcpy(_str,s);
_size = s_len;
return *this;
}
string& string::operator=(const string& str){
return operator=(str._str);
}
string& string::operator=(char c){
reserve(1);
_str[0] = c;
_str[1] = '\0';
_size = 1;
return *this;
}
void string::resize(size_t n,char c){
if((int)n>_size){
reserve(n);
for(int i = _size;i<(int)n;i++){
_str[i] = c;
}
_size = n;
_str[_size]='\0';
}else if((int)n>=0&&(int)n<_size){
erase(n);
}
}
void string::swap(string& str){
if(&str == this) return;//如果交换自己直接返回
char* tmp = str._str;
str._str = _str;
_str = tmp;
int tmp_s = str._size;
int tmp_c = str._capacity;
str._size = _size;
_size = tmp_s;
str._capacity = _capacity;
_capacity = tmp_c;
}
std::ostream& operator<< (std::ostream& out,const string& s){
for(int i = 0;i
#include "my_string.h"
void test01(){
string s1("ssssss");
string s2;
string s3(s1);
cout<
测试结果: