c++之封装——string类型的实现

以前在C语言中并没有string这个内置类型,但是到了c++里面就可以使用了,c++中可以定义string变量,对string类型的变量可以进行各种操作,包括相加、相减、赋值等等,就和int ,double类型相似,但string是一个字符串。要实现这些操作并不像C语言的内置类型一样那么简单,直接数据进行运算就可以。
string的实现得益与c++的封装特性,封装是c++的三大特性之一,string类型其实是在char*类型的基础上进行一层封装。其实质还是基于C语言的内置类型数据上的操作。
简单的创建一个类,类名为string,类的私有成员为char*类型指针,为指针动态指针开辟一段空间,就可以在这段空间上进行操作了。

class String            
{
public:
 String(char *str = NULL) //构造
 {
  if (str == NULL)
  {
   _pstr = new char[1];
   *_pstr = '\0';
  }
  else
  {
   _pstr = new char[strlen(str) + 1];
   strcpy(_pstr, str);
  }

   ~String()
 {
  if (this->_pstr != NULL)
  {
   delete[] _pstr;
   _pstr = NULL;
  }
 }

private:
 char *_pstr;
};

对于string的操作有很多,这里主要实现string的一些运算和比较,比如比较两个字符串是否相等,在以前没有string类的时候,我们比较两个字符串需要写一个函数,对字符串进行遍历,在string中原理大致相同,但有了string类之后,就可以随时调用类的方法,在类中实现“==“运算符的重载,给出公用接口就可以了。

class String         
{
public:
 String(char *str = NULL) //构造
 {
  if (str == NULL)
  {
   _pstr = new char[1];
   *_pstr = '\0';
  }
  else
  {
   _pstr = new char[strlen(str) + 1];
   strcpy(_pstr, str);
  }

   ~String()
 {
  if (this->_pstr != NULL)
  {
   delete[] _pstr;
   _pstr = NULL;
  }
 }

 bool operator==(const String&s)
 {
  char* s1 = _pstr;
  char* s2 = s._pstr;
  while (*s1!='\0'&&*s2!='\0')
  {
   if (*s1 == *s2)
   {
    s1++;
    s2++;
    if (*s1 == '\0'&&*s2 == '\0')
    {
     return true;
    }
   }
   else
    return false;
  } 
  if (*s1 == '\0'&&*s2 == '\0')
  {
   return true;
  }
  else
  {
   return false;
  }
 }
private:
 char *_pstr;
};

此时,我们便可以轻松比较两个字符串是否相等

int main()
{
   string s1("abcd");
   string s2("cdef");
   int a=(s1==s2);
   return 0;
}

在进行string赋值操作时,由于字符串所占的空间可能超出为原指针开辟的空间,所以要进行判断并重新开辟空间

class String            
{
public:
 String(char *str = NULL)
 {
  if (str == NULL)
  {
   _pstr = new char[1];
   *_pstr = '\0';
  }
  else
  {
   _pstr = new char[strlen(str) + 1];
   strcpy(_pstr, str);
  }
 }

 ~String()
 {
  if (this->_pstr != NULL)
  {
   delete[] _pstr;
   _pstr = NULL;
  }
 }

 String& operator=(const String& s)
 {
  if (this != &s)
  {
   char *tmp = new char[strlen(s._pstr) + 1];
   strcpy(tmp, s._pstr);
   delete[] _pstr;             //释放原来的内存
   this->_pstr = tmp;
  }
  return *this;
 }

 private:
 char *_pstr;
};

下面是一个比较完整的string类的实现

class String           
{
public:
 String(char *str = NULL)
 {
  if (str == NULL)
  {
   _pstr = new char[1];
   *_pstr = '\0';
  }
  else
  {
   _pstr = new char[strlen(str) + 1];
   strcpy(_pstr, str);
  }

 }
 String(const String& s)
  :_pstr(new char[strlen(s._pstr)+1])
 {
  strcpy(_pstr, s._pstr);
 }

 ~String()
 {
  if (this->_pstr != NULL)
  {
   delete[] _pstr;
   _pstr = NULL;
  }
 }

 String& operator=(const String& s)
 {
  if (this != &s)
  {
   char *tmp = new char[strlen(s._pstr) + 1];
   strcpy(tmp, s._pstr);
   delete[] _pstr;
   this->_pstr = tmp;
  }
  return *this;
 }

 bool operator>(const String&s)
 {
  char* s1 = _pstr;
  char* s2 = s._pstr;
  while (*s1)
  {
   if (*s1 > *s2)
   {
    return true;
   }
   else if (*s1 < *s2)
   {
    return false;
   }
   else
   {
    s1++;
    s2++;
   }
  }
  return false;
 }

 bool operator>=(const String&s)
 {
  char* s1 = _pstr;
  char* s2 = s._pstr;
  while (*s1)
  {
   if (*s1 >= *s2)
   {
    return true;
   }
   else 
   {
    return false;
   }
  }
 }


 bool operator<(const String&s)
 {
  char* s1 = _pstr;
  char* s2 = s._pstr;
  while (*s1)
  {
   if (*s1 < *s2)
   {
    return true;
   }
   else if (*s1 > *s2)
   {
    return false;
   }
   else
   {
    s1++;
    s2++;
   }
  }
  return true;
 }

 bool operator<=(const String&s)
 {
  char* s1 = _pstr;
  char* s2 = s._pstr;
  while (*s1)
  {
   if (*s1 <= *s2)
   {
    return true;
   }
   else
   {
    return false;
   }
  }
 }

 bool operator==(const String&s)
 {
  char* s1 = _pstr;
  char* s2 = s._pstr;
  while (*s1!='\0'&&*s2!='\0')
  {
   if (*s1 == *s2)
   {
    s1++;
    s2++;
    if (*s1 == '\0'&&*s2 == '\0')
    {
     return true;
    }
   }
   else
    return false;
  } 
  if (*s1 == '\0'&&*s2 == '\0')
  {
   return true;
  }
  else
  {
   return false;
  }
 }

 bool operator!=(const String&s)
 { 
  if (_pstr == s._pstr)
   return false;
  else
   return true;
 }

 size_t Size()  // 模拟strlen
 {
  int count = 0;
  char* s = _pstr;
  while (*s)
  {
   count++;
   s++;
  }
  return count;
 }

 // 检测s是否是当前对象的子串
 bool StrStr(const String& s) // 模拟strstr
 {
  char *Str = _pstr;
  char* Substr = s._pstr;
  char *TStr;
  char *TSub;
  while (*Str)
  {
   TStr = Str;
   TSub = Substr;
   while(*Str == *Substr)
   {
    Str++;
    Substr++;
    if (*Substr == '\0')
    {
     return true;
    }
   }
   Str = TStr;
   Substr = TSub;
   Str++;
  }
  return false;
 }

 // 将当前对象从pos位置开始复制count个字符到p所指向的空间中
 // 返回复制到p中有效字符的个数 
 size_t Copy(char* p, size_t pos, size_t count)  // 模拟strcpy
 {
  assert(p);
  if (count <= 0)
  {
   return 0;
  }
  char *s1 = _pstr;
  while (pos--)
  {
   s1++;
  }
  if (*s1 = '\0'&&count>0)
  {
   *p = *s1;
   return 1;

  }
  int CopyNumber = 0;

  while (--count)
  {
   if (*s1 != '\0')
   {
    *p = *s1;
    p++;
    s1++;
    CopyNumber++;
   }
   else
   {
    return CopyNumber;
   }
  }
 }

private:
 char *_pstr;
};

string类有多种实现方式,前面只是比较常规的一种,仅供参考。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值