实现自定义string类

转自天之痕博客


C++继承了C语言中以空字符结尾的C风格字符串以及包括strcpy()函数的函数库,但这些函数没有集成到面向对象的框架中,标准库中包含一个String类,它提供了一套封装好的数据以及处理这些数据的函数,使用这个类前可以先实现一下自定义的String类,以便熟悉这个框架。

代码清单:

  1. #include <iostream>
  2. #include <string.h>
  3. using namespace std;
  4. class String
  5. {
  6. public:
  7.   //constructors
  8.   String();
  9.   String(const char *const);
  10.   String(const String &);
  11.   //destructors
  12.   ~String();
  13.   //操作符重载
  14.   char & operator[] (unsigned short offset);  //[]重载非常量版本
  15.   char operator[] (unsigned short offset) const;  //[]重载常量版本
  16.   String operator+ (const String &);
  17.   void operator+= (const String &);
  18.   String & operator= (const String &);
  19.   //常规存取器方法
  20.   unsigned short GetLen()const { return itsLen; }
  21.   const char* GetString() const { return itsString; }
  22. private:
  23.   String(unsigned short); //私有构造函数
  24.   char* itsString;
  25.   unsigned short itsLen;
  26. };
  27. String::String()
  28. {
  29.   itsString=new char[1];
  30.   itsString[0]='/0';
  31.   itsLen=0;
  32. }
  33. String::String(unsigned short len)
  34. {//传入长度,创建一个String对象
  35.   itsString=new char[len+1];
  36.   for (unsigned short i=0;i<=len;i++)
  37.   {
  38.     itsString[i]='/0';
  39.   }
  40.   itsLen=len;
  41. }
  42. String::String(const charconst cString)
  43. {//传入字符串地址,创建一个String对象
  44.   itsLen=strlen(cString);
  45.   itsString=new char[itsLen+1];
  46.   for (unsigned short i=0;i<itsLen;i++)
  47.     itsString[i]=cString[i];
  48.   itsString[itsLen]='/0';
  49. }
  50. String::String(const String & rhs)
  51. {//copy constructors
  52.   itsLen=rhs.GetLen();
  53.   itsString=new char[itsLen+1];
  54.   for(unsigned short i=0;i<itsLen;i++)
  55.     itsString[i]=rhs[i];
  56.   itsString[itsLen]='/0';
  57. }
  58. String::~String()
  59. {
  60.   delete [] itsString;
  61.   itsLen=0;
  62. }
  63. String& String::operator=(const String & rhs)
  64. {
  65.   if(this== &rhs)
  66.     return *this;
  67.   delete [] itsString;
  68.   itsLen=rhs.GetLen();
  69.   itsString=new char[itsLen+1];
  70.   for(unsigned short i=0;i<itsLen;i++)
  71.     itsString[i]=rhs[i];
  72.   itsString[itsLen]='/0';
  73.   return *this;
  74. }
  75. char & String::operator [](unsigned short offset)
  76. {//若偏移大于字符串长度,返回最后一个元素,否则返回字符串偏移处的字符
  77.   if(offset>itsLen)
  78.     return itsString[itsLen-1];
  79.   else
  80.     return itsString[offset];
  81. }
  82. char String::operator [](unsigned short offset) const
  83. {
  84.   if(offset>itsLen)
  85.     return itsString[itsLen-1];
  86.   else
  87.     return itsString[offset];  
  88. }
  89. String String::operator+ (const String& rhs)
  90. {
  91.   unsigned short totalLen=itsLen+rhs.GetLen();
  92.   String temp(totalLen);
  93.   unsigned short i,j;
  94.   for(i=0;i<itsLen;i++)
  95.     temp[i]=itsString[i];
  96.   for(j=0;j<rhs.GetLen();j++,i++)
  97.     temp[i]=rhs[j];
  98.   temp[totalLen]='/0';
  99.   return temp;
  100. }
  101. void String::operator+= (const String& rhs)
  102. {
  103.   unsigned short rhsLen=rhs.GetLen();
  104.   unsigned short totalLen=itsLen+rhsLen;
  105.   String temp(totalLen);
  106.   unsigned short i,j;
  107.   for(i=0;i<itsLen;i++)
  108.     temp[i]=itsString[i];
  109.   for(j=0;j<rhsLen;j++,i++)
  110.     temp[i]=rhs[j];
  111.   temp[totalLen]='/0';
  112.   *this=temp;
  113. }
  114. int main()
  115. {
  116.   String s1("initial test");
  117.   cout << "S1:/t"<<s1.GetString()<<endl;
  118.   char* temp="Hello World";
  119.   s1=temp;
  120.   cout << "S1:/t"<<s1.GetString()<<endl;
  121.   char tempTwo[20];
  122.   strcpy(tempTwo,"; nice to be here!");
  123.   s1+=tempTwo;
  124.   cout << "tempTwo:/t" << tempTwo <<endl;
  125.   cout << "S1:/t"<<s1.GetString()<<endl;
  126.   cout << "S1[4]:/t" <<s1[4] <<endl;
  127.   s1[4]='x';
  128.   cout << "S1[4]:/t" <<s1[4] <<endl;
  129.   
  130.   cout <<"S1[999]:/t" <<s1[999] <<endl;
  131.   String s2(" Another string");
  132.   String s3;
  133.   s3=s1+s2;
  134.   cout << "S3:/t"<<s3.GetString()<<endl;
  135.   String s4;
  136.   s4="Why does this work?";
  137.   cout << "S4:/t"<<s4.GetString()<<endl;
  138.   return 0;
  139. }
  140. //S1:     initial test
  141. //S1:     Hello World
  142. //tempTwo:        ; nice to be here!
  143. //S1:     Hello World; nice to be here!
  144. //S1[4]:  o
  145. //S1[4]:  x
  146. //S1[999]:        !
  147. //S3:     Hellx World; nice to be here! Another string
  148. //S4:     Why does this work?
  149. //Press any key to continue

需要注意的几点是:

1.重载'='运算符的函数中,其实返回值是没有作用的,你可以任意返回void或int,凭你喜好。

2.重载[ ]运算符的函数有2个,const类型和非const类型,在142行中,调用的是非const类型,其余对于const类型的对象或对象引用,非const类型函数访问时非法的。

3.第137行中 s1+=tempTwo 这里tempTwo字符数组怎么能和对象进行'+'运算呢? 原来第10行声明了一个可根据字符数组创建String的构造函数,因此编译器根据提供的字符数组创建一个临时String,并将其传递给赋值运算符。这被称为隐式强制转换或升格。如果没有声明并实现接受字符数组作为参数的构造函数,这种赋值将导致错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值