VC驿站--编写一个精简版的string类.doc_第1页
VC驿站--编写一个精简版的string类.doc_第2页
VC驿站--编写一个精简版的string类.doc_第3页
VC驿站--编写一个精简版的string类.doc_第4页
VC驿站--编写一个精简版的string类.doc_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

编写一个精简版的string类该类的具体功能如下所示.1 计算字符串的长度,类似于string类的size或者length2 可对字符串进行赋值,如String str=hello world;3 可将char型字符串直接赋给String型字符串,如:String str=Hello world;char ch10=not at all;str=ch;4 可如同对象那样将字符串进行初始化,String str(Mother);5 可将两个字符串相加,然后将合并后的字符串赋给另一个字符串,如String str=s2+s3;6 可执行加等操作(+=),也就是将第1个字符串与第2个字符串相加,然后再赋给第1个字符串,如:String s1+=s27 可对两个字符串进行比较,如str1=str2,str1str2.8 可根据字符串的大小自动调节保存字符串的数组的大小。9 限制数组越界10通过成员函数输出字符串,如s1.getlen()。11 通过重载输出运算符输出字符串,如:string s1(hello),s2(good);couts1输入字符串,如:cins1s2创建String类上节简单地对精简版的String类的功能进行了介绍,本节首先实现这个String类。我们知道C+自带的String类在声明一个字符串后,如:String s;该字符串s仅仅是声明,并未初始化,因此该字符串是个空字符,只保存了结束符号0。我们首先来实现这个功能。由于对象的创建是通过构造函数来实现的,因此我们可以通过默认构造函数来构造一个空字符串。通过String类的默认构造函数实现空字符串。程序代码如下:1. #include 2. using namespace std;3. class String4. 5. public:6. String();7. int getlen()constreturn len;8. private:9. int len;10. char *str;11. ;12. String:String()13. 14. len = 0;15. str=new char1;16. str0=0;17. 18. int _tmain(int argc, _TCHAR* argv)19. 20. String s1;21. couts1.getlen();22. system(pause);23. return 0;24. 输出:0分析:第6行声明了一个默认构造函数,第1217行是该函数的定义部分。第14行将所创建的字符串的长度len设置为0,len在第9行定义。第15行在堆中创建一个char型数组,该数组只有一个元素,str保存该数组的地址,char型指针str在第10行定义。第16行将char型数组str中唯一一个元素保存结束字符0,因此该char型数组变成了一个字符串,一个长度为0的空字符串。main函数开始于第19行,第20行用我们创建的String类声明了一个字符串s1,然后第21行输出该字符串的长度,为0.成员函数getlen()在第7行定义,它的作用是返回字符串长度len的值。创建可以自动调节大小的String类字符串对象本节我们将在已创建空字符串的基础上创建一个有字符的字符串,并且该字符串课根据字符的长度自动调节数组的大小。要实现这个功能,我们需要一个带参数的构造函数,如: 1. String:String(const char*const ch)2. 3. len = strlen(ch);4. str = new charlen+1;5. for(int i=0;ilen;i+)6. stri = chi;7. strlen=0;8. 复制代码这样,假如我们定义并初始化了一个字符串,如String s(Hello world); 就会自动调用这个带一个参数的构造函数,同时将hello world传递到函数中,ch接收了这个字符串,第3用strlen计算hello world的长度,也就是ch的长度,该长度同时赋给String 类的私有成员变量len。第4行在堆中创建了一个char型数组,它的长度是len+1,最后一个字符用来保存结束符0。该char型数组的内存地址赋给String类的私有指针成员变量str。第56行是一个for循环,从字符串ch第1个字符开始,也就是hello world,每循环一次,即将ch中的一个字符赋给str指向的在堆中创建的char型数组,一直到结束字符前的最后一个字符为止。最后一行用str指向的在堆中创建的char型数组中的最后一个元素保存结束符号0。这样,我们就可以创建一个恰好能容纳所有字符的char型字符串数组。创建可自动调节大小的String类字符串对象。程序代码如下: 1. #include 2. using namespace std;3. class String4. 5. public:6. String();7. String(const char*const ch);8. int getlen()constreturn len;9. const char*getstr()constreturn str;10. private:11. int len;12. char *str;13. ;14. String:String()15. 16. cout默认构造函数n;17. len = 0;18. str=new char1;19. str0=0;20. 21. String:String(const char*const ch)22. 23. cout构造函数n;24. len = strlen(ch);25. str = new charlen+1;26. for(int i=0;ilen;i+)27. stri = chi;28. strlen=0;29. 30. int _tmain(int argc, _TCHAR* argv)31. 32. String s1;33. couts1:s1.getstr()t共s1.getlen()字符endl;34. String s2(study);35. couts2:s2.getstr()t共s2.getlen()字符endl;36. char *temp = help me;37. String s3(temp);38. couts3:s3.getstr()t共s3.getlen()字符len)4. return strlen-1;5. else6. return strlength7. 复制代码第1行重载了属于String类的下标运算符函数operator,该函数有一个整型参数,即数组的下标length,该下标值会传递到函数体中进行判断,假如下标超过了数组长度,那么返回数组长度-1,也就是最后一个可见字符,假如该下标长度不超过数组长度,那么返回该下标的数组元素。这样,就算用户超出数组长度地输入或者输出一个字符,如:couts999,由于超过数组长度返回的是最后一个字符,因此不会出现在超出数组末尾修改数据的现象,这无形中就提高了代码的安全性。增加限制数组越界功能的String类的例子如下所示。限制数组越界。程序代码如下: 1. #include 2. using namespace std;3. class String4. 5. public:6. String();7. String(const char *const ch);8. char&operator(int length); /按引用返回的重载下标运算符函数9. int getlen()constreturn len;10. const char *getstr()constreturn str;11. private:12. int len;13. char *str;14. ;15. String:String()16. 17. len = 0;18. str = new char1;19. str0=0;20. 21. String:String(const char *const ch)22. 23. len = strlen(ch);24. str = new charlen+1;25. for(int i=0;ilen)32. return strlen-1;33. else34. return strlength;35. 36. int _tmain(int argc, _TCHAR* argv)37. 38. String s1;39. couts1:s1.getstr()t 共s1.getlen()字符endl;40. String s2(study);41. couts2:s2.getstr()t 共s2.getlen()字符endl;42. char *temp = help me;43. String s3(temp);44. couts3:s3.getstr()t 共s3.getlen()字符s3999;46. couts3:s3.getstr()t 共s3.getlen()字符endl;47. couts3999:s3999endl;48. system(pause);49. return 0;50. 分析:第8行声明了重载下标运算符函数operator,该函数按别名方式返回char型字符,第3238行是该函数的定义部分。第48行调用operator函数,下标值999被传递到operator函数中,由于该下标值大于数组长度len,因此返回len-1个数组元素,也就是最后一个可见字符。cin流对象将用户输入的第1个字符保存在该数组最后一个可见字符的位置处。第49行首先输出该数组的所有元素,即所有可见字符,我们看到最后一个字符由原来的e变成了z。第50行又试图超出数组末尾输出字符,结果这一错误被operator函数捕获,因此返回的仍然是数组的最后一个元素,即字符z。用复制构造函数实现字符串的赋值功能本节我们再为这个String类添加赋值功能,该功能可以再构造对象的时候进行赋值,如:string s4=s3;我们知道,在构造一个对象时用另一个对象来初始化该对象的数据成员,需要调用一个函数,该函数就是复制构造函数,默认的复制构造函数都是浅层复制,由于我们需要在两个对象间复制的成员是个指针,因此必须重写复制构造函数,重写的复制构造函数实现对象之间的深层复制的过程如下: 1. String:String(const String &rs)2. 3. len = rs.getlen();4. str = new charlen+1;5. for(int i=0;ilen)4. return strlen-1;5. else6. return strlength;7. 复制代码由于我们是在复制构造函数中调用该函数,并且临时对象在复制构造函数结束后即被销毁,因此没必要按地址返回临时对象的数据成员,这里的operator重载下标运算符函数按值返回char型字符,同时在函数体前面加了const修饰符,表示该函数可以操作const对象。这样,两个同名函数的类型不同,就可以做到对该函数的重载。const修饰符实现重载。程序代码如下: 1. #include 2. using namespace std;3. class A4. 5. public:6. A(int i,int j)x=i;y=j;7. void set(int s1,int s2)x=s1,y=s2;8. void print()coutxendl;9. void print()constcoutylen)4. return strlen-1;5. else6. return strlength;7. 复制代码函数体中对下标值进行判断,假如下标值超过数组字符长度,那么返回该数组最后一个可见字符,否则的话,返回处于该下标位置的数组元素。我们看到,由于该函数体中只是返回this对象的某个数组元素,并不对该this对象的某个成员进行修改,因此这里在函数体前面用了const修饰符,这样可避免在该函数中发生试图修改当前对象的某个成员的错误现象,同时又实现了对operatorp下标运算符函数的重载。但是这里又有一个问题,那就是假如传递进来的下标值是一个负数,也就是说用户不小心输入了一个负数,由于下标不能为负,并且编译器也不会限制用户输入一个负数,因此这回造成一个隐藏的错误。解决的办法是在对传入的length加条判断语句,如:if(lengthlen&length0)return strlen-1;或者直接将length定义为unsigned short int(无符号短整型),如:char String:operaot(unsigned short int length)const这样,Sting类的私有成员变量len也要定义为无符号短整型变量,如:unsigned short int len;复制构造函数实现两个对象的赋值。程序代码如下: 1. #include 2. using namespace std;3. class String4. 5. public:6. String();7. String(const String&rs); /复制构造函数8. String(const char *const ch);9. char &operator(unsigned short int length);10. char operator(unsigned short int length)const;11. unsigned short int getlen()constreturn len;12. const char *getstr()constreturn str;13. private:14. unsigned short int len;15. char *str;16. ;17. String:String()18. 19. len = 0;20. str = new char1;21. str0 = 0;22. 23. String:String(const String&rs)24. 25. cout复制构造函数执行.n;26. len = rs.getlen();27. str = new charlen+1;28. for(int i=0;ilen;i+)29. stri=rsi;30. strlen=0;31. 32. String:String(const char *const ch)33. 34. len = strlen(ch);35. str = new charlen+1;36. for(int i=0;ilen;i+)37. stri = chi;38. strlen=0;39. 40. char &String:operator(unsigned short int length)41. 42. coutlen)44. return strlen-1;45. else46. return strlength;47. 48. char String:operator(unsigned short int length)const49. 50. coutlen)52. return strlen-1;53. else54. return strlength;55. 56. int _tmain(int argc, _TCHAR* argv)57. 58. String s1;59. couts1:s1.getstr()t 共s1.getlen()字符endl;60. String s2(study);61. couts2:s2.getstr()t 共s2.getlen()字符endl;62. char *temp = help me;63. String s3(temp);64. couts3:s3.getstr()t 共s3.getlen()字符s3-999;66. couts3:s3.getstr()t 共s3.getlen()字符endl;67. couts3-999:s3-999endl;68. String s4=s3;69. couts4:s4.getstr()t 共s4.getlen()字符endl;70. system(pause);71. return 0;72. 复制代码用重载赋值运算符函数实现真正的字符串赋值功能楼上介绍赋值其实不是真正的赋值,而是利用赋值构造函数实现的对一个新对象的初始化,本节我们来学习真正的赋值功能,该功能允许String类的两个对象直接进行赋值,如:String s1(hello),s2(name);s1 = s2;也允许将未命名字符串直接赋给String类的一个对象,如:s1 = hello world;为实现该功能,我们首先需要重载赋值运算符,因为默认的赋值运算符只能实现变量的赋值功能,不能实现对象之间的赋值操作。我们前面学习了重载赋值运算符operator=,因此这里可以直接写出该函数。 1. String& String:operator =(const String &rs)2. 3. if(this=&s)4. return *this;5. delete str;6. len = rs.getlen();7. str = new charlen+1;8. for(int i=0;ilen;i+)9. 10. stri = rsi;11. 12. strlen = 0;13. return *this;14. 复制代码该函数接受一个String类对象,并将该对象的别名修饰为const,传递到函数体中,在函数体第1行首先检测传递进来的对象是否与当前调用的对象相等,也就是等号左边的对象是否等于右边的对象。假如相等,那么返回左边的对象,否则删除左边对象的str成员,也就是字符串成员。然后根据右边字符串的长度创建一个字符串,再加1用于保存结束空字符。接着将右边对象的字符串成员中的每个字符赋给左边对象的字符串成员,最后用空字符结束左边对象的字符串并按引用方式返回左边对象。返回左边对象的别名是为下一次赋值做准备,如: s1 = s2 = s3;从右侧开始将s3的值赋给s2后,返回s2的别名,然后再将s2的别名赋给s1,从而实现赋值符 = 的重载。 1. #include stdafx.h2. #include 3. using namespace std;4. class String5. 6. public:7. String();8. String(const char *const ch);9. String(const String &rs);10. char &operator(unsigned short int length);11. char operator(unsigned short int length)const;12. String &operator = (const String &rs);13. int getlen()constreturn len;14. private:15. unsigned short int len;16. char *str;17. ;18. String:String()19. 20. len = 0;21. str = new char1;22. str0 = 0;23. 24. String:String(const char *const ch)25. 26. len = strlen(ch);27. str = new charlen+1;28. for(int i=0;ilen;i+)29. stri = chi;30. strlen = 0;31. 32. String:String(const String &rs)33. 34. len = rs.getlen();35. str = new charlen+1;36. for(int i=0;ilen)43. return strlen-1;44. else45. return strlength;46. 47. char String:operator (unsigned short int length)const48. 49. if(lengthlen)50. return strlen-1;51. else52. return strlength;53. 54. String& String:operator =(const String &rs)55. 56. if(this=&rs)57. return *this;58. delete str;59. len = rs.getlen();60. str = new charlen+1;61. for(int i=0;ilen;i+)62. 63. stri = rsi;64. 65. strlen = 0;66. return *this;67. 68. int _tmain(int argc, _TCHAR* argv)69. 70. String s1 = hello world;71. String s2;72. s2 = s1;73. couts2.getlen()endl;74. s2 = name;75. couts2.getlen()endl;76. system(pause);77. return 0;78. 用重载输出运算符operator()函数实现字符串的输出在String类中增加operator()函数可以直接输出String类对象的字符串成员,因此我们可用该函数代替成员函数getlen(),该函数的定义与实现如下所示。 1. friend ostream &operator (ostream &o,const String &str)2. 3. ostr.str;4. return o;5. 复制代码我们将函数添加到String类中,补充后的程序如下:实现String类对象的输出。 1. #include stdafx.h2. #include 3. using namespace std;4. class String5. 6. public:7. String();8. String(const char *const ch);9. String(const String &rs);10. char &operator(unsigned short int length);11. char operator(unsigned short int length)const;12. String &operator = (const String &rs);13. int getlen()constreturn len;14. friend ostream &operator (ostream &o,const String &str)15. 16. ostr.str;17. return o;18. 19. private:20. unsigned short int len;21. char *str;22. ;23. String:String()24. 25. len = 0;26. str = new char1;27. str0 = 0;28. 29. String:String(const char *const ch)30. 31. len = strlen(ch);32. str = new charlen+1;33. for(int i=0;ilen;i+)34. stri = chi;35. strlen = 0;36. 37. String:String(const String &rs)38. 39. len = rs.getlen();40. str = new charlen+1;41. for(int i=0;ilen)48. return strlen-1;49. else50. return strlength;51. 52. char String:operator (unsigned short int length)const53. 54. if(lengthlen)55. return strlen-1;56. else57. return strlength;58. 59. String& String:operator =(const String &rs)60. 61. if(this=&rs)62. return *this;63. delete str;64. len = rs.getlen();65. str = new charlen+1;66. for(int i=0;ilen;i+)67. 68. stri = rsi;69. 70. strlen = 0;71. return *this;72. 73. int _tmain(int argc, _TCHAR* argv)74. 75

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论