全新力作—C++ string类的模拟实现

引言:本篇文章主要实现一个自定义字符串类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()

  • 交换两个字符串的值

头文件“my_string.h”:

#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);

my_string.cpp

#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

main.cpp

#include "my_string.h"
void test01(){
  string s1("ssssss");
  string s2;
  string s3(s1);
  cout<

测试结果: 

全新力作—C++ string类的模拟实现_第1张图片

你可能感兴趣的:(C++,linux,c++,开发语言)