【1】应用示例
1 #include <vector>
2 #include <cassert>
3 #include <string>
4 #include <iostream>
5 using namespace std;
6
7 class String
8 {
9 public:
10 String();
11 String(int n, char c);
12 String(const char* source);
13 String(const String& s);
14 String(String&& s);
15 String& operator=(char* s);
16 String& operator=(const String& s);
17 String& operator=(String&& s);
18 ~String();
19
20 char& operator[](int i);
21 const char& operator[](int i) const;
22 String& operator+=(const String& s);
23 String& operator+=(const char* s);
24
25 friend ostream& operator<<(ostream& out, String& s);
26 friend ostream& operator<<(ostream& out, const String& s);
27 friend istream& operator>>(istream& in, String& s);
28
29 friend bool operator<(const String& left, const String& right);
30 friend bool operator>(const String& left, const String& right);
31 friend bool operator==(const String& left, const String& right);
32 friend bool operator!=(const String& left, const String& right);
33
34 int getSize() const;
35 void setSize(int nSize);
36 char* getData() const;
37 void setData(char* pData);
38
39 private:
40 void init();
41
42 private:
43 int m_size;
44 char* m_data;
45 };
46
47 void String::init()
48 {
49 m_data = new char[1];
50 assert(m_data != NULL);
51 *m_data = '\0';
52 m_size = 0;
53 }
54
55 String::String()
56 {
57 cout << "call String()" << endl;
58 init();
59 }
60
61 String::String(int n, char c)
62 {
63 cout << "call String(int n, char c)" << endl;
64 m_data = new char[n + 1];
65 assert(m_data != NULL);
66 m_size = n;
67 char* temp = m_data;
68 while (n--)
69 {
70 *temp++ = c;
71 }
72 *temp = '\0';
73 }
74
75 String::String(const char* source)
76 {
77 cout << "call String(const char* source)" << endl;
78 if (NULL == source)
79 {
80 init();
81 }
82 else
83 {
84 m_size = strlen(source);
85 m_data = new char[m_size + 1];
86 assert(m_data != NULL);
87 strcpy_s(m_data, (m_size + 1), source);
88 }
89 }
90 String::String(const String& s)
91 {
92 cout << "call String(const String& s)" << endl;
93 m_data = new char[s.m_size + 1];
94 assert(m_data != NULL);
95 strcpy_s(m_data, (s.m_size + 1), s.m_data);
96 m_size = s.m_size;
97 }
98
99 String::String(String&& s)
100 {
101 cout << "call move ctor" << endl;
102 m_data = s.getData();
103 m_size = s.getSize();
104 s.setData(NULL);
105 s.setSize(0);
106 }
107
108 String& String::operator=(char* s)
109 {
110 cout << "call operator=(char* s)" << endl;
111
112 if (m_data != NULL)
113 {
114 delete []m_data;
115 }
116 m_size = strlen(s);
117 m_data = new char[m_size + 1];
118 assert(m_data != NULL);
119 strcpy_s(m_data, (m_size + 1), s);
120 return (*this);
121 }
122
123 String& String::operator=(const String& s)
124 {
125 cout << "call operator=(const String& s)" << endl;
126
127 if (this == &s)
128 {
129 return *this;
130 }
131 if (m_data != NULL)
132 {
133 delete []m_data;
134 }
135 m_size = strlen(s.m_data);
136 m_data = new char[m_size + 1];
137 assert(m_data != NULL);
138 strcpy_s(m_data, (m_size + 1), s.m_data);
139 return (*this);
140 }
141
142 String& String::operator=(String&& s)
143 {
144 cout << "call move operator=" << endl;
145
146 if (this == &s)
147 {
148 return (*this);
149 }
150 if (m_data != NULL)
151 {
152 delete[]m_data;
153 }
154 m_data = s.getData();
155 m_size = s.getSize();
156 s.setData(NULL);
157 s.setSize(0);
158 return (*this);
159 }
160
161 String::~String()
162 {
163 if (m_data != NULL)
164 {
165 delete[]m_data;
166 m_data = NULL;
167 m_size = 0;
168 }
169 }
170
171 char& String::operator[](int i)
172 {
173 return m_data[i];
174 }
175
176 const char& String::operator[](int i) const
177 {
178 return m_data[i];
179 }
180
181 String& String::operator+=(const String& s)
182 {
183 int len = m_size + s.m_size + 1;
184 char* pTemp = m_data;
185 m_data = new char[len];
186 assert(m_data != NULL);
187 strcpy_s(m_data, (m_size + 1), pTemp);
188 strcat_s(m_data, len, s.m_data);
189 m_size = len - 1;
190 delete[]pTemp;
191 return (*this);
192 }
193
194 String& String::operator+=(const char* s)
195 {
196 if (NULL == s)
197 {
198 return (*this);
199 }
200 int len = m_size + strlen(s) + 1;
201 char* pTemp = m_data;
202 m_data = new char[len];
203 assert(m_data != NULL);
204 strcpy_s(m_data, (m_size + 1), pTemp);
205 strcat_s(m_data, len, s);
206 m_size = len - 1;
207 delete[]pTemp;
208 return (*this);
209 }
210
211 int String::getSize() const
212 {
213 return m_size;
214 }
215
216 void String::setSize(int nSize)
217 {
218 this->m_size = nSize;
219 }
220
221 char* String::getData() const
222 {
223 return m_data;
224 }
225
226 void String::setData(char* pData)
227 {
228 if (NULL == pData)
229 {
230 init();
231 }
232 else
233 {
234 m_data = pData;
235 }
236 }
237
238 ostream& operator<<(ostream& out, String& s)
239 {
240 for (int i = 0; i < s.getSize(); ++i)
241 {
242 out << s[i] << " ";
243 }
244 return out;
245 }
246
247 ostream& operator<<(ostream& out, const String& s)
248 {
249 for (int i = 0; i < s.getSize(); ++i)
250 {
251 out << s[i] << " ";
252 }
253 return out;
254 }
255
256 istream& operator>>(istream& in, String& s)
257 {
258 char p[50];
259 in.getline(p, 50);
260 s = p;
261 return in;
262 }
263
264 bool operator<(const String& left, const String& right)
265 {
266 int i = 0;
267 while (left[i] == right[i] && left[i] != 0 && right[i] != 0)
268 i++;
269
270 return (left[i] - right[i] < 0);
271 }
272
273 bool operator>(const String& left, const String& right)
274 {
275 int i = 0;
276 while (left[i] == right[i] && left[i] != 0 && right[i] != 0)
277 i++;
278
279 return (left[i] - right[i] > 0);
280 }
281
282 bool operator==(const String& left, const String& right)
283 {
284 int i = 0;
285 while (left[i] == right[i] && left[i] != 0 && right[i] != 0)
286 i++;
287
288 return (left[i] == right[i]);
289 }
290
291 bool operator!=(const String& left, const String& right)
292 {
293 int i = 0;
294 while (left[i] == right[i] && left[i] != 0 && right[i] != 0)
295 i++;
296
297 return (left[i] != right[i]);
298 }
299
300 int main()
301 {
302 std::vector<String> stringVector;
303
304 String str(3, 'a');
305 String str1(str);
306 String str2("asdf");
307 String str3 = str2;
308
309 cout << "str: " << str << endl;
310 cout << "str1: " << str1 << endl;
311 cout << "str2: " << str2 << endl;
312 cout << "str3: " << str3 << endl;
313
314 stringVector.push_back(str);
315 stringVector.push_back(str1);
316 stringVector.push_back(str2);
317 stringVector.push_back(str3);
318
319 // 第一种方式
320 cout << "the first way: " << endl;
321 for (auto item : stringVector)
322 {
323 cout << item << endl;
324 }
325
326 // 第二种方式:引用,可以修改元素值
327 cout << "the second way: " << endl;
328 for (auto& item : stringVector)
329 {
330 item += "baidu";
331 cout << item << endl;
332 }
333
334 // 第三种方式
335 cout << "the third way: " << endl;
336 for (auto & const item : stringVector)
337 {
338 cout << item << endl;
339 }
340
341 // 第四种方式
342 cout << "the four way: " << endl;
343 for (auto const & item : stringVector)
344 {
345 cout << item << endl;
346 }
347
348 // 第五种方式:万能引用
349 //参考:https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
350 cout << "the five way: " << endl;
351 for (auto&& item : stringVector)
352 cout << item << endl;
353
354 // 第六种方式
355 cout << "the six way: " << endl;
356 for (auto& item : { "abc", "def", "hij" })
357 cout << item << endl;
358
359 // 第七种方式
360 cout << "the seven way: " << endl;
361 for (auto& item : { 100, 200, 300 })
362 cout << item << endl;
363
364 #if 0
365 // 第七种方式:编译错误
366 cout << "the seven way: " << endl;
367 for (int& item : { 100, 200, 300 })
368 cout << item << endl;
369 #endif
370
371 system("pause");
372 }