今天帮着一位大二的学弟写了一个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 }