关于如何来构造一个String类

  今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实现.....

  内容写的过于简单,没有涉及到其他格式的如考虑utf_8.这儿单纯的考虑了char的使用.......

  1 #define  _CRT_SECURE_NO_WARNINGS
  2 #include<iostream>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<windows.h>
  6 using namespace std;
  7 
  8 class MyString {
  9 
 10 public :
 11     MyString(const char * str = NULL) ;  //默认构造函数
 12     MyString(const MyString  & mystr);  //复制构造函数
 13     ~MyString() {
 14         if (test != NULL) delete[] test;
 15     };
 16         //析构函数
 17     int length();  //返回字符串长度
 18     void print();  //打印
 19     char at(int pos) ;  //查找第i个字符
 20     MyString & operator = (const MyString  &other); //等号操作符重载
 21    MyString & operator = (const  char  * str ); //等号操作符重载
 22 private:
 23     char * test;
 24 };
 25 
 26 //构造函数
 27 MyString::MyString(const  char * str) {
 28 
 29 
 30     if (str == NULL)
 31     {
 32         test = new char[1];
 33         *test = '\0';
 34     }
 35     else
 36     {
 37         int length = strlen(str);
 38         test = new char[length + 1];
 39         strcpy(test, str);  //复制
 40     }
 41 }
 42 
 43 MyString::MyString(const MyString  & mystr)   //复制构造函数
 44 {
 45     char * pstr = mystr.test; 
 46     test = new char [strlen(pstr)+1];  //开辟空间
 47     strcpy(test, mystr.test);    //复制类容
 48 }
 49 
 50 //返回长度
 51 int MyString::length() {
 52     
 53     int i = 0;
 54     if (test == NULL) return 0;
 55     while (test[i] != '\0') i++;
 56     return i;
 57 }
 58 
 59 void MyString::print() {
 60 
 61     if (test != NULL) {
 62         //printf("%s\n",test);
 63          puts(test);  //这样可以输出空格
 64     }
 65 }
 66 
 67 char MyString::at(int pos) {
 68 
 69     if (test != NULL) {
 70         int len = strlen(test);
 71         if (len <=pos) {
 72             throw out_of_range("位置超过字符串长度!");
 73         }
 74         else {
 75             return test[pos];
 76         }
 77     } {
 78         throw out_of_range("字符串为空!");
 79     }
 80 }
 81 
 82 MyString & MyString::operator =(const MyString & aa)
 83 {
 84     if (this == &aa)//当地址相同时,直接返回;
 85         return *this;
 86         delete[] test;//当地址不相同时,删除原来申请的空间,重新开始构造;
 87     int length = strlen(aa.test);
 88     test = new char [length + 1];
 89     strcpy(test, aa.test);
 90     return *this;
 91   
 92 }
 93 
 94 MyString & MyString::operator = (const  char  * str) //等号操作符重载
 95 {
 96 
 97     MyString  * ss = new MyString (str);
 98     return *ss;
 99 }
100 
101 
102 int main(){
103 
104     char *pp = "sadasd";
105     MyString  aa = "abcd";
106     aa.print();  //显示
107     cout << "长度为:" << aa.length();
108     cout << "显示abcd第二个元素的内容"<<aa.at(1)<<endl;
109     
110     MyString  *str = new MyString(pp);  //对于指针而言
111     str->print();
112     cout << "长度为:" << str->length();
113     cout << "显示sadasd第二个元素的内容" << str->at(1)<<endl;
114 
115     MyString  bb(aa);  //对于复制构造函数而言
116     bb.print();
117     cout << "长度为:" << bb.length();
118     cout << "显示abcd第二个元素的内容" << bb.at(1)<<endl;
119     str->print();
120     getchar();
121 }

对于这一点,后来又加深了一些基本模式,简略的实现以下String类吧!

  1 #define  _CRT_SECURE_NO_WARNINGS
  2 #include<iostream>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 using namespace std;
  6 
  7 template < typename  T >
  8 
  9 class MyString {
 10 
 11 public :
 12 
 13     MyString(const T * str = NULL) ;
 14         //默认构造函数
 15     MyString(const MyString<T>  & mystr);  //复制构造函数
 16     ~MyString() {
 17         if (test != NULL) delete[] test;
 18     };
 19         //析构函数
 20     int length();  //返回字符串长度
 21     void print();  //打印
 22     T at(int pos);
 23     MyString<T> & operator + (const MyString<T>  &aa); //等号操作符重载
 24     MyString<T> & operator + (const  T  * str); //等号操作符重载
 25     MyString<T> & operator = (const MyString<T>  &aa); //等号操作符重载
 26     MyString<T> & operator = (const  T  * str );     //等号操作符重载
 27 
 28 private:
 29     T * test;
 30 
 31 };
 32 
 33 template < typename  T >
 34 MyString<T> &  MyString<T>::operator + (const MyString<T>  &aa) {
 35     
 36     T  *str =test;
 37     int lena = -1 , lenb=-1;
 38        lena=strlen(aa.test);
 39        lenb = strlen(test);
 40        if (lena> 0) {
 41            test = new T[lena+lenb];
 42            strcpy(test, strcat(str, aa.test));
 43 
 44        }
 45        return *this;
 46 }
 47 
 48 
 49 template < typename  T >
 50 MyString<T> & MyString<T>::operator + (const T * str) {
 51 
 52     T  * str = test;
 53     int lena = -1, lenb = -1;
 54     lena = strlen(str);
 55     lenb = strlen(test);
 56     if (lena > 0) {
 57             test = new T[lena + lenb];
 58         strncpy(test, strcat(str, str));
 59     }
 60     return *this;
 61 }
 62 
 63 //构造函数
 64 template < typename  T >
 65 MyString<T>::MyString(const  T * str) {
 66 
 67 
 68     if (str == NULL)
 69     {
 70         test = new T[1];
 71         *test = '\0';
 72     }
 73     else
 74     {
 75         int length = strlen(str);
 76         test = new T[length + 1];
 77         strcpy(test, str);  //复制
 78     }
 79 }
 80 
 81 template < typename  T >
 82 MyString<T>::MyString(const MyString<T>  & mystr)   //复制构造函数
 83 {
 84     T * pstr = mystr.test; 
 85     test = new T [strlen(pstr)+1];  //开辟空间
 86     strcpy(test, mystr.test);    //复制类容
 87 }
 88 
 89 //返回长度
 90 template < typename  T >
 91 int MyString<T>::length() {
 92     
 93     int i = 0;
 94     if (test == NULL) return 0;
 95     while (test[i] != '\0') i++;
 96     return i;
 97 }
 98 template < typename  T >
 99 void MyString<T>::print() {
100 
101     if (test != NULL) {
102         //printf("%s\n",test);
103          puts(test);  //这样可以输出空格
104     }
105 }
106 template < typename  T >
107 T MyString<T>::at(int pos) {
108 
109     if (test != NULL) {
110         int len = strlen(test);
111         if (len <=pos) {
112             throw out_of_range("位置超过字符串长度!");
113         }
114         else {
115             return test[pos];
116         }
117     } {
118         throw out_of_range("字符串为空!");
119     }
120 }
121 
122 template < typename  T >
123 MyString<T> & MyString<T>::operator =(const MyString<T> & aa)
124 {
125     if (this == &aa)//当地址相同时,直接返回;
126         return *this;
127         delete[] test;//当地址不相同时,删除原来申请的空间,重新开始构造;
128     int length = strlen(aa.test);
129     test = new T [length + 1];
130     strcpy(test, aa.test);
131     return *this;
132   
133 }
134 
135 template < typename  T >
136 MyString<T> & MyString<T>::operator = (const  T  * str) //等号操作符重载
137 {
138 
139     MyString<T>  * ss = new MyString<T> (str);
140     return *ss;
141 }
142 
143 
144 int main(){
145 
146     char *pp = "sadasd";
147     MyString<char> aa = "abcd";
148     aa.print();  //显示
149     cout << "长度为:" << aa.length();
150     cout << "显示abcd第二个元素的内容"<<aa.at(1)<<endl;
151     
152     MyString<char>  *str = new MyString<char>(pp);  //对于指针而言
153     str->print();
154     cout << "长度为:" << str->length();
155     cout << "显示sadasd第二个元素的内容" << str->at(1)<<endl;
156 
157     MyString<char>  bb(aa);  //对于复制构造函数而言
158     bb.print();
159     cout << "长度为:" << bb.length();
160     cout << "显示abcd第二个元素的内容" << bb.at(1)<<endl;
161     str->print();
162     MyString<char>  sc="你好,北京人";
163     sc.print();
164     sc = sc + bb;
165     sc.print();
166     getchar();
167     return 0;
168 }

  String类的先关补充.....

  1 /*
  2 String类的功能为:
  3   1.构造函数
  4   2.重载赋值操作符
  5   3.重载下标操作符
  6   4.重载关系操作符
  7   5.重载转换操作符
  8   6.析构函数
  9 */
 10 #include<iostream>
 11 #include<string.h>
 12 #include<assert.h>
 13 #include<string>
 14 using namespace std;
 15 
 16 
 17 
 18 class String {
 19 
 20     //重载输出操作符
 21     friend ostream & operator << (ostream &out, String & str);
 22     friend istream & operator >> (istream &in, String & str);
 23     //重载关系操作符
 24     friend bool operator == (const String &src , const String &op);
 25     friend bool operator != (const String &src, const String &op);
 26     friend bool operator  < (const String &src, const String &op);
 27 public :
 28     //定义构造函数
 29     String();  //default
 30     String(const char * str); //elements
 31     String(const String &str); //copy
 32    //重载赋值操作符
 33     String & operator =(const String & str);
 34     String & operator =(const char * str);
 35     String & operator =(const char str);
 36     //+=重载运算操作符
 37     String & operator +=(const String & str);
 38     String & operator +=(const char * str);
 39     String & operator +=(const char str);
 40 
 41    //重载[]操作符
 42     char & operator [] (int index );
 43     //重载转换操作符
 44     operator char*();
 45     ~String();
 46 private:
 47     char *gg  ;      //字符指针
 48 };
 49 
 50 ostream & operator << (ostream &out, String & str) {
 51     out << str.gg ;
 52     return  out;
 53 }
 54 
 55 istream & operator >> (istream &in, String & str)
 56 {
 57     in >> str.gg;
 58     return in ;
 59 }
 60 
 61 bool operator == (const String &src, const String &op) {
 62     return strcmp(src.gg , op.gg) == 0;
 63 }
 64 
 65 bool operator != (const String &src, const String &op)
 66 {
 67     return strcmp(src.gg , op.gg )!=0;
 68 }
 69 
 70 bool operator  < (const String &src, const String &op) {
 71     return strcmp(src.gg ,op.gg )<0;
 72 }
 73 
 74 String::String() {
 75     gg = new char[1];
 76     gg = '\0';
 77 };
 78 
 79 String::String(const char * str) {
 80     int var = strlen(str);
 81     gg = new char[var+1];
 82     strcpy(gg ,str);
 83 }
 84 
 85 String::String(const String &str) {
 86     int var = strlen(str.gg);
 87     gg = new char[var + 1];
 88     strcpy(gg, str.gg);
 89 }
 90 
 91 
 92 String & String::operator =(const String & str) {
 93     if (this == &str) return *this;
 94     delete gg;
 95     int var = strlen(str.gg);
 96     gg = new char[var + 1];
 97     strcpy(gg, str.gg);
 98     gg[var] = '\0';
 99     return  *this;
100 }
101 
102 char & String::operator [] (int index) {
103     assert(index>=0&&index<strlen(gg));
104     return gg[index];
105 }
106 
107 
108 String & String::operator =(const char * str) {
109     if (strcmp(gg,str)==0) return *this;
110     int var = strlen(str);
111     gg = new char(var + 1);
112     strcpy(gg, str);
113     gg[var] = '\0';
114     return *this;
115 }
116 
117 String & String::operator = (const char str) {
118 
119     gg = new char(2);
120     gg[0] = str;
121     gg[1] = '\0';
122     return *this;
123 }
124 
125 String::operator char *() {
126     return gg;
127 }
128 
129 String::~String() {
130     delete gg;
131 }
132 
133 String & String::operator +=(const String & str) {
134     int var = strlen(str.gg);
135     if (gg == NULL)
136     {
137         gg = new char(var+1);
138         strcpy(gg,str.gg);
139         gg[var] = '\0';
140     }
141     else {
142         char *p = gg;
143         int vat = strlen(p) + var;
144         gg = new char(vat+var);
145         strcpy(gg,p);
146         delete p;
147         strcat(gg,str.gg);
148         gg[vat] = '\0';
149     }
150     return *this;
151 }
152 
153 String & String::operator +=(const char * str) {
154 
155     int var = strlen(str);
156     if (gg == NULL)
157     {
158         gg = new char(var + 1);
159         strcpy(gg, str);
160         gg[var] = '\0';
161     }
162     else {
163         char *p = gg;
164         int vat = strlen(p) + var;
165         gg = new char(vat + var);
166         strcpy(gg, p);
167         delete p;
168         strcat(gg, str);
169         gg[vat] = '\0';
170     }
171     return *this;
172 
173 }
174 String & String::operator +=(const char str) {
175 
176     if (gg == NULL)
177     {
178         gg = new char(2);
179         gg[0] == str;
180         gg[1] = '\0';
181     }
182     else {
183         char *p = gg;
184         int vat = strlen(p)+1;
185         gg = new char(vat + 2);
186         strcpy(gg, p);
187         delete p;
188         gg[vat - 1] = str;
189         gg[vat] = '\0';
190     }
191     return *this;
192 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏拭心的安卓进阶之路

深入理解 Java 反射:Class (反射的入口)

深入理解 Java 反射系列: 深入理解 Java 反射:Class (反射的入口) 深入理解 Java 反射:Field (成员变量) 深入理解 Java ...

296100
来自专栏WindCoder

Java漫谈-数组

在Java语言中,数组是对象(An object is a class instance or an array.),而且是动态创建的。

22010
来自专栏程序员的碎碎念

php Array数组知识总结

PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量...

73270
来自专栏柠檬先生

Java 基础标识符

标识符: 程序员为自己定义的类,方法或者变量等起的名称。     标识符由大写字母,数字,下划线(_)和美元符号组成,但不能以数字开头。 Java 语言中严格区...

22150
来自专栏全沾开发(huā)

JavaScript中的比较运算符

JavaScript中的比较运算符 JavaScript中的比较运算符粗略的可以分为两种: 相等运算符(==、===、!==)这些 ...

35570
来自专栏塔奇克马敲代码

第 14 章 重载运算与类型转换

25360
来自专栏企鹅号快讯

Python网络爬虫之正则表达式

正则表达式非Python独有,在Python中通过re库模块实现。 ? 下面是一些常见的匹配模式 ? re.match re.match尝试从字符串的起始位置匹...

199100
来自专栏黑泽君的专栏

java基础学习_面向对象(上)02_day07总结

============================================================================= ==...

8310
来自专栏用户2442861的专栏

java中的内部类总结

http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.html

10130
来自专栏欧阳大哥的轮子

C++运算符重载详解

C++语言的一个很有意思的特性就是除了支持函数重载外还支持运算符重载,原因就是在C++看来运算符也算是一种函数。比如一个 a + b 的加法表达式也可以用函数的...

31930

扫码关注云+社区

领取腾讯云代金券