C++学习:string的模拟实现

string大家肯定都会用,那么我们来简单实现下string,并非完全重现string,意思到了就好。

这次就不用声明定义分离了。实现直接放头文件里了,也方便大家看。

目录

一:结构和迭代器

二:构造 析构 赋值

三:reserve和resize

四:find

五:substr

六:尾插 +=

七:insert erase

八:比较符号

九:cout cin

十:其他


一:结构和迭代器

namespace hhh
{  class string
  { public:
   typedef char* iterator ;
   typedef const char* const_iterator; 
   iterator begin() {return _str;}
   iterator end() {return _str+_size;}
   const_iterator begin()const {return _str;}
   const_iterator end()  const {return _str+_size;}
 
 
   
 
const static size_t npos;//这个你们肯定string里见过
 
   //还有其他成员函数
 
   private:
   char* _str;
   size_t _size;
   size_t _capacity;
  };
const size_t string::npos=-1;
 
 
 
}

二:构造 析构 赋值

string(const char* str="") //""里面不用放东西 自带'\0'的
 :_size(strlen(str))
 ,_capacity(_size)
 { _str=new char[_capacity+1];
    strcpy(_str,str);
 } //构造
 void swap(string& s)
{ std::swap(_str,s._str);
  std::swap(_size,s._size);
  std::swap(_capacity,s._capacity);
}
string(const string&s)
:_str(nullptr)
,_size(0)
,_capacity(0)
{ string tmp(s._str);
   swap(tmp);
} //拷贝构造
string& operator=(string tmp) //传引用传参还得先构造个新的tmp 传值直接构造完了 步骤更少
{ swap(tmp);
  return *this;
}
~string()
{ delete[] _str;
  _str=nullptr;
  _size=_capacity=0;
}

三:reserve和resize

void reserve(size_t n)
{ if(n>_capacity)
 { char*tmp=new char[n+1];
   strcpy(tmp,_str);
   delete[] _str;
   _str=tmp;
   _capacity=n;
}
}
void resize(size_t n,char ch='\0')
{ if(n<_size) {_str[n]='\0';_size=n;}
  else
{ while(_size!=n)
   { _str[_size]=ch;
     _size++;
   }
  _str[n]='\0';
}


}

四:find

char& operator[](size_t pos)
{ assert(pos<_size);
 return _str[pos];

}
const char& operator[](size_t pos) const
{ assert(pos<_size);
 return _str[pos];

}
size_t find(char ch,size_t pos=0)
{ for(int i=pos;pos<_size;pos++)
  {if(_str[i]==ch) return i;}

 return npos;
}
size_t find(const char* sub,size_t pos=0)
{ char*p=strstr(_str+pos,sub);
  if(p) return p-_str;
  else return npos;
 
}

五:substr

string substr(size_t pos,size_t len=npos)
{ size_t end=pos+len;
 string s;
  if(len=npos||end>=_size) end=_size;
  for(int i=pos;i<end;i++) s+=_str[i]; //+=下面会实现
  return s;
}

六:尾插 +=

void push_back(char ch)
{ if(_size==_capacity) reserve(_capacity==0?4:2*_capacity);
  _str[_size]=ch;
  _size++;
  _str[_size]='\0';
}
void append(const char* str)
{ int len=strlen(str);
  if(_size+len>_capacity) reserve(_size+len);
  strcpy(_str+_size,str);
  _size+=len;

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

七:insert erase

void insert(int pos,char ch)
{  assert (pos<=_size);
if(_size==_capacity) reserve(_capacity==0?4:2*_capacity);
  int end=_size;
  while(end>=pos)
{ _str[end]=_str[end-1];
 end--;

}
_str[pos]=ch;
_size++;
}
void insert(int pos,const char* str)
{  assert(pod<=_size);
   int len=strlen(str);
   if(_size+len>_capacity) reserve(_size+len);
  int end=pos+len;
  while(end>=pos) 
  { _str[end]=_str[end-1];
    end--;
  }
  strncpy(_str+pos,str,len);
  _size+=len;
}
void erase(int pos,int len=npos)
{ assert(pos<_size);
  if(end+len>=_size||len==npos) 
  { _str[pos]='\0';
    _size=pos;
   }
  else
{ int begin=pos+len;
  while(begin>=_size)
 { _str[begin-len]=_str[begin];
   begin++;
}
_size-=len;

}

}

为啥很多地方不用size_t ,因为像end这种头插是有可能减着减着变成-1了,但是无符号啊。另外如果end是int pos是size_t ,符号两边类型不同会发生类型提升 ,所以要么强转int或避开-1,太麻烦了。

八:比较符号

        bool operator<(const string& s) const
		{
			return strcmp(_str, s._str) < 0;
		}

		bool operator==(const string& s) const
		{
			return strcmp(_str, s._str) == 0;
		}

		bool operator<=(const string& s) const
		{
			return *this < s || *this == s;
		}

		bool operator>(const string& s) const
		{
			return !(*this <= s);
		}

		bool operator>=(const string& s) const
		{
			return !(*this < s);
		}

		bool operator!=(const string& s) const
		{
			return !(*this == s);
		}

九:cout cin

ostream& operator<<(ostream&out,const string& s)
{ for(auto ch:s) out<<ch;
  return out;
}

istream& operator>>(istream&in,const string&s)
{ s.clear();
  char buff[129];//你也可以直接reserve 但是这样可以节省空间 因为buff会自己销毁掉
  int i=0;
  char ch;
  ch=in.get();//不用这个拿不到空格 换行 cin和scanf这方面差不多 get类似getchar
  while(ch!=' '&&ch!='\0')
 { buff[i++]=ch;
   if(i==128)
   { buff[i]='\0';
     s+=buff;
     i=0;
   }
   ch=in.get();

}
  if(i!=0)
 {  buff[i]='\0';
s+=buff;


}
return in;
}


void clear()
{ _str[0]='\0';
  _size=0;
}

十:其他

       size_t capacity() const
		{
			return _capacity;
		}

		size_t size() const
		{
			return _size;
		}

		const char* c_str() const
		{
			return _str;
		}

感谢你看到这,大家共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值