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




编程是一种快乐,享受代码带给我的乐趣!!!