服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 代码分析c++中string类

代码分析c++中string类

2021-06-22 13:52瞭望天空 C/C++

本篇内容通过详细的源代码详细分析了C++中string类的用法以及知识点,有兴趣的读者们参考下。

一:回顾

(1)c++中的string类是在面试中和笔试中经常考的题目; 工程代码免费下载 string类的自行实现

(2)c++中的string类和fstream类合起来是处理外部数据的利器;

(3)string类经常用到find find_first_of find_first_not_of find_last_of find_last_not_of substr replace等,以及联合使用来达到java中的split和trim

(4) 使用friend 仅仅是在类中进行声明的非内部 却可以访问内部成员的外部函数,而且在外部不再需要friend关键字;它与成员函数的区别是,friend和外部函数不含有this对象指针;本文用到了const 定义的全局最大值最小值变量(代替#define)

(5) 有些函数返回的是MyString& 、Char& 等(引用),MyString、Char 等(传值)这得看你返回的对象是函数的局部变量还是全局变量(或者类当前对象成员变量);前者只能返回一个MyString、Char 等;后者强烈建议返回MyString& 、Char& 等(引用);

(6)有些函数的参数是const MyString& ,有些是MyString& (引用);这是为什么?前者是把外部值传提到子函数内部,且不允许改变;后者是作为函数的返回值传递进去的,返回的结果为函数的处理结果(而不用函数自身返回值了)。

二:下面是简单的实现了一下string类,参照的是STL源码,但是自己理解的还是不够深,难免有一些错误,请各位指教

(1)MyString.h文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#ifndef MYSTRING_H
#define MYSTRING_H
#include "MyExcept.h"
#include <cstring>
#include <iostream>
const int INI_MAX = 0x7fffffff;//2^32npos
const int INI_MIN = 0x80000000;// -2^32
const int npos = 0xffffffff;// npos
using namespace std;
 
class MyString
{
  public:
  // constructor
  MyString();//
  MyString(const MyString &);//
  MyString(const char *);
  MyString(const size_t,const char);
  // destructor
  ~MyString();
  // attributes
 
  size_t length();// 字符串长度
  bool isEmpty();// 返回字符串是否为空
  const char* c_str();// 返回c风格的trr的指针
  // friend funs
  // read writer operations
  friend ostream& operator<< (ostream&, const MyString&);
  friend istream& operator>> (istream&, MyString&);
  //add operation
  friend MyString operator+(const MyString&,const MyString&);
  // compare operations
  friend bool operator==(const MyString&,const MyString&);
  friend bool operator!=(const MyString&,const MyString&);
  friend bool operator<(const MyString&,const MyString&);
  friend bool operator<=(const MyString&,const MyString&);
  friend bool operator>(const MyString&,const MyString&);
  friend bool operator>=(const MyString&,const MyString&);
  // 成员函数实现运算符重载,其实一般需要返回自身对象的,成员函数运算符重载会好一些
  // index operation
  char& operator[](const size_t);
  const char& operator[](const size_t)const;
  // =
  MyString& operator=(const MyString&);
  // +=
  MyString& operator+=(const MyString&);
  // +=
  //MyString operator+=(const MyString&); cannot be overloaded
  // 成员操作函数
  // substr
  MyString substr(size_t pos,const size_t n);
  // append
  MyString& append(const MyString&);
  //insert
  MyString& insert(size_t,const MyString&);
  //assign 替换
  MyString& assign(MyString&,size_t,size_t);
  // erase 删除
  MyString& erase(size_t,size_t);
  //find_first_of 查找某一个字符 size_t 是非符号数的,重载
  // 查找在字符串中第一个与str中的某个字符匹配的字符,返回它的位置。
  //搜索从index开始,如果没找到就返回string::npos
  int find_first_of(const char* str,size_t index=0);
  int find_first_of(const char ch,size_t index=0);
  int find_first_of(const MyString &,size_t index=0);
  // 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops
  int find_first_not_of(const char* str,size_t index=0);
  int find_first_not_of(const char ch,size_t index=0);
  int find_first_not_of(const MyString&,size_t index=0);
  // swap
  void swap(MyString& lhs,MyString& rhs);
  // replace_all
  MyString& replace_all(const char oldc,const char newc=NULL);
  MyString& replace(size_t index,size_t num1,size_t num2,const char ch);
  //find
  int find(const char* str,size_t index=0);
  int find(const MyString& str,size_t index=0);
  int find(const char ch,size_t index=0);
 
 
  //private
  private:
  char *p_str;
  size_t strLength;
};
#endif // MYSTRING_H

(2)MyString.cpp文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
#include "MyString.h"
#include <cassert>
 
// constructor
  MyString::MyString():p_str(NULL),strLength(0){}
 
  MyString::MyString(const MyString &str)//
  {
    if(NULL == str.p_str)
    {
      return;
    }
    strLength = str.strLength;
    p_str = new char[strLength+1];
    strcpy(p_str,str.p_str);
  }
  MyString::MyString(const char *str)
  {
    if(NULL == str)
    {
      return;
    }
    strLength = strlen(str);
    p_str = new char[strLength+1];
    strcpy(p_str,str);
  }
  MyString::MyString(const size_t len,const char ch)
  {
    if(NULL == ch)
    {
      return;
    }
    strLength = len;
    p_str = new char[strLength+1];
    for(size_t i=0;i<strLength;i++)
    {
      p_str[i] = ch;
    }
    p_str[strLength] = '\0';// 因为strset以'\0'结束的
    cout << p_str << " &&" << endl;
    //strset(p_str,ch);
    //cout << p_str[0] << ",,,"<<strlen(p_str) << "," << strLength << endl;
  }
  // destructor
  MyString::~MyString()
  {
    delete[] p_str;
  }
 
  // attributes
  size_t MyString::length()// 字符串长度
  {
    return strLength;
  }
  bool MyString::isEmpty()// 返回字符串是否为空
  {
    return strLength==0?true:false;
  }
  const char* MyString::c_str()
  {
    return p_str;
  }
  // 为什么不是引用呢??? friend 使用在类里面进行声明的,外面就不需要了,而且友元函数不属于类的成员函数,所以不用MyString::
  // ostream
  ostream& operator<< (ostream& out,const MyString &str)
  {
    if(str.p_str != NULL)
    {
      out << str.p_str;
    }
    return out;
  }
  // istream,一个是const另一个不是,根据变还是不变
  istream& operator>> (istream& in, MyString& str)
  {
    char tmp[100];// 临时字符串
    if(in>>tmp)
    {
      delete[] str.p_str;
      str.strLength = strlen(tmp);
      str.p_str = new char[str.strLength+1];
      strcpy(str.p_str,tmp);
    }
    return in;
  }
  // + 加
  MyString operator+(const MyString& lhs,const MyString& rhs)
  {
    MyString ret;
    ret.strLength = lhs.strLength + rhs.strLength;
    ret.p_str = new char[ret.strLength+1];
    strcpy(ret.p_str,lhs.p_str);
    strcat(ret.p_str,rhs.p_str);
    return ret;
  }
  // compare operations
  bool operator==(const MyString& lhs,const MyString& rhs)
  {
    return strcmp(lhs.p_str,rhs.p_str)==0?true:false;
  }
  bool operator!=(const MyString& lhs,const MyString& rhs)
  {
    return strcmp(lhs.p_str,rhs.p_str)!=0?true:false;
  }
  bool operator<(const MyString& lhs,const MyString& rhs)
  {
    return strcmp(lhs.p_str,rhs.p_str)<0?true:false;
  }
  bool operator<=(const MyString& lhs,const MyString& rhs)
  {
    return strcmp(lhs.p_str,rhs.p_str)<=0?true:false;
  }
  bool operator>(const MyString& lhs,const MyString& rhs)
  {
    return strcmp(lhs.p_str,rhs.p_str)>0?true:false;
  }
  bool operator>=(const MyString& lhs,const MyString& rhs)
  {
    return strcmp(lhs.p_str,rhs.p_str)>=0?true:false;
  }
  // 成员函数实现运算符重载
  // index operation
  char& MyString::operator[](const size_t index)
  {
    if(index<0 || index>=strLength)
    {
      throw Outofbond() ;
    }
    return p_str[index];
  }
  const char& MyString::operator[](const size_t index)const
  {
    if(index<0 || index>=strLength)
    {
      throw Outofbond();
    }
    return p_str[index];
  }
   // = 赋值构造函数(判断是否是自身) 为什么要这样删除呢?
  MyString& MyString::operator=(const MyString& other)
  {
    if(this != &other)
    {
      if(strLength<other.strLength)
      {
        delete[] p_str;
        p_str = new char[other.strLength+1];
      }
      strLength = other.strLength;
      strcpy(p_str,other.p_str);
    }// 这样可能会产生多余的未释放的空间
    return *this;
  }
  // += 相当于返回的是备份的,内部对象的销毁,不影响的 和 下面的完全不一样的
//  MyString MyString::operator+=(const MyString& other)
//  {
//    if(NULL == other.p_str)
//    {
//      return *this;
//    }
//    MyString ret;
//    ret.strLength = strLength + other.strLength;
//    ret.p_str = new char[ret.strLength+1];
//    strcpy(ret.p_str,p_str);
//    strcat(ret.p_str,other.p_str);
//    return ret;
//  }
  // 返回的是当前对象的引用,当前对象就在调用函数里,所以不会销毁的
  // 判断一下是否是自身相加
  MyString& MyString::operator+=(const MyString& other)
  {
    if(NULL == other.p_str)
    {
      return *this;
    }
    if(this == &other)
    {
      MyString copy(*this);
      return *this += copy;
    }// 必须判断是否相等的,而且要+=的,这样相当于调用了自身,但是这次直接下面去了,不进入if的
    strLength += other.strLength;
    //strLength *= 2;
    char *p_old = p_str;
    p_str = new char[strLength+1];
    strcpy(p_str,p_old);
    strcat(p_str,other.p_str);
    delete[] p_old;// 删除旧的空间
    return *this;
  }
  // 成员操作函数
  // substr 返回应用是不行的,错误的;取从pos开始的n个字符组成的子串
  //MyString& MyString::substr(size_t pos,const size_t n)
  MyString MyString::substr(size_t pos,const size_t n)
  {
    if((pos+n)>=strLength)
    {
      throw Outofbond();
    }
    MyString ret;
    ret.strLength = n;
    //ret.p_str = new char[n+1];
    ret.p_str = new char[ret.strLength+1]; //也可以
    for(size_t i=0;i<n;i++)
    {
      ret.p_str[i] = p_str[pos+i];
    }
    ret.p_str[n] = '\0';
//    for(size_t i=0;i<ret.strLength;i++)
//    {
//      ret[i] = (*this)[pos+i];
//      cout << ret[i] << ",,";
//    }// 也行的,利用刚刚重载的【】,这样更好,不用再次判断越界了,不知道为什么,报错误的
//    ret[ret.strLength] = '\0';
    return ret;
  }
  // append 同 += 追加到末尾
  MyString& MyString::append(const MyString& other)
  {
    *this += other;// 利用刚刚那重载的+=
    return *this;
  }
  //insert 从pos开始的插入other
  MyString& MyString::insert(size_t pos,const MyString& other)
  {
    if(pos<0 || pos>=strLength)
    {
      throw Outofbond();
    }
    char *p_old = p_str;
    strLength += other.strLength;
    p_str = new char[strLength+1];
    for(size_t i=0;i<pos;i++)
    {
      *(p_str+i) = *(p_old+i);
    }
    for(size_t i=pos;i<other.strLength+pos;i++)
    {
      *(p_str+i) = other.p_str[i-pos];
    }
    for(size_t i=other.strLength+pos;i<strLength;i++)
    {
      *(p_str+i) = p_old[i-other.strLength];
    }
    *(p_str+strLength) = '\0';
    return *this;
  }
  //assign 替换 用other的POS开始的n对应替换this的pos开始的
  MyString& MyString::assign(MyString&other,size_t pos,size_t n)
  {
//    if(pos<0 || pos>=strLength)
//    {
//      throw Outofbond();
//    }
    assert(pos>0 && pos<strLength);// assert 的好处
    assert(pos+n<other.strLength);
    if(strLength < pos + n)
    {
      char *p_old = p_str;
      strLength = pos + n;
      p_str = new char[strLength+1];
      for(size_t i=0;i<pos;i++)
      {
        *(p_str+i) = *(p_old+i);
      }
      delete[] p_old;
    }
    for(size_t i=pos;i<pos+n;i++)
    {
      *(p_str+i) = other.p_str[i];
    }
    *(p_str+pos+n) = '\0';
    return *this;
  }
  // erase 删除 这个方法并不是很好的,并没有释放所erase的空间,请看下面的
//  MyString& MyString::erase(size_t pos,size_t n)
//  {
//    if((pos+n)>strLength)
//    {
//      throw Outofbond();
//    }
//    size_t index = pos + n;
//    while(*(p_str+index)!='\0')
//    {
//      *(p_str+index-n) = *(p_str+index);
//      ++index;
//    }
//    *(p_str+index-n) = '\0';
//    return *this;
//  }
  // erase 删除 从pos开始的n个字符
  MyString& MyString::erase(size_t pos,size_t n)
  {
    if((pos+n)>strLength)
    {
      throw Outofbond();
    }
    char *p_old = p_str;
    strLength -= n;
    p_str = new char[strLength+1];
    for(size_t i=0;i<pos;i++)
    {
      p_str[i] = p_old[i];
    }
    for(size_t i=pos;i<strLength;i++)
    {
      p_str[i] = p_old[i+n];
    }
    *(p_str+strLength) = '\0';
    return *this;
  }
  //find_first_of 查找某一个字符 size_t 是非符号数的
  // 查找在字符串中第一个与str中的某个字符匹配的字符,返回它的位置。
  //搜索从index开始,如果没找到就返回string::npos
  int MyString::find_first_of(const char* str,size_t index)
  {
    if(NULL == str || index >=strLength)
      return npos;
    int tmp_len = strlen(str),j;
    size_t flag,min_index = INI_MAX;
    for(j=0;j<tmp_len;j++)
    {
      flag = npos;
      for(size_t i=index;i<strLength;i++)
      {
        if(str[j] == p_str[i])
        {
          flag = i;
          break;
        }
      }
//      indexs[j] = flag;
      if(flag != npos)
      {
        min_index = min_index<flag?min_index:flag;
      }
    }
//    for(j=0;j<tmp_len;j++)
//    {
//      if(indexs[j]!=npos)
//        min = min<indexs[j]?min:indexs[j];
//    }
    if(min_index == INI_MAX)
    {
      return npos;
//      min_index = npos;
//      cout << "---npos----" << min_index << ",,,,";
    }
    return min_index;
  }
  int MyString::find_first_of(const char ch,size_t index)
  {
    if(NULL == ch || index >=strLength)
      return npos;
    int j;
    size_t flag = npos;
    for(size_t i=index;i<strLength;i++)
    {
      if(ch == p_str[i])
      {
        flag = i;
        break;
      }
    }
    return flag;
  }
  int MyString::find_first_of(const MyString& str,size_t index)
  {
    if(NULL == str || index >=strLength)
      return npos;
    int j;
    size_t flag,min_index = INI_MAX;
    for(j=0;j<str.strLength;j++)
    {
      flag = npos;
      for(size_t i=index;i<strLength;i++)
      {
        if(str[j] == p_str[i])
        {
          flag = i;
          break;
        }
      }
      if(flag != npos)
      {
        min_index = min_index<flag?min_index:flag;
      }
    }
    if(min_index == INI_MAX)
    {
      return npos;
    }
    return min_index;
  }
  // 在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。
  //搜索从index开始。如果没找到就返回string::nops O(N^2)
  int MyString::find_first_not_of(const char *str,size_t index)
  {
    if(NULL == str || index >=strLength)
      return npos;
    size_t i=0,j=0;
    size_t tmp_len = strlen(str);
    for(i=index;i<strLength;i++)
    {
      for(;j<tmp_len;j++)
      {
        if(p_str[i]==str[j])
          break;
      }
      if(j==tmp_len)
        break;// 根据跳出的内层for的条件判断,找到即结束循环
    }
    if(i==strLength)
      return npos;// 未找到,// 根据跳出的内层for的条件判断,找到即结束循环
    return i;
  }
  int MyString::find_first_not_of(const MyString& str,size_t index)
  {
    if(NULL == str || index >=strLength)
      return npos;
    size_t i=0,j=0;
    for(i=index;i<strLength;i++)
    {
      for(;j<str.strLength;j++)
      {
        if(p_str[i]==str[j])
          break;// 如果相等 本轮i就无效了,进行下一轮
      }
      if(j==str.strLength)
        break;// 根据跳出的内层for的条件判断,找到即结束循环
    }
    if(i==strLength)
      return npos;// 未找到,// 根据跳出的内层for的条件判断,找到即结束循环
    return i;
  }
  int MyString::find_first_not_of(const char ch,size_t index)
  {
    if(NULL == ch || index >=strLength)
      return npos;
    size_t i=0;
    for(i=index;i<strLength;i++)
    {
      if(p_str[i]!=ch)// 跟上面的略微不同,找一个不等就可以了
        break;
    }
    if(i==strLength)
      return npos;// 未找到,// 根据跳出的内层for的条件判断,找到即结束循环
    return i;
  }
  // swap 都得变得,所以非const
  void MyString::swap(MyString& lhs,MyString& rhs)
  {
    lhs.strLength ^= rhs.strLength;
    rhs.strLength ^= lhs.strLength;
    lhs.strLength ^= rhs.strLength;
    char *p_tmp = rhs.p_str;
    rhs.p_str = lhs.p_str;
    lhs.p_str = p_tmp;
  }
  // replace_all 这个东西还是不太好弄的啊,不是很理想
  MyString& MyString::replace_all(const char oldc,const char newc)
  {
    if(NULL == oldc)
    {
      return *(this);
    }
    for(size_t i=0;i<strLength;i++)
    {
      if(p_str[i] == oldc)
      {
        p_str[i] = newc;
      }
    }
    return *(this);
  }
  MyString& MyString::replace(size_t index,size_t num1,size_t num2,const char ch)
  {
 
  }
  // find 函数
  int MyString::find(const char* str,size_t index)
  {
    assert(str!=NULL&&index<strLength);
    // kmp 中的getnext函数
    size_t len = strlen(str);
    size_t next[len+1];
    size_t j,k;
    next[0] = npos;
    j = 0;
    k = npos;
    while(j<len)
    {
      if(k==npos || str[j]==str[k])
      {
        j++;
        k++;
        next[j] = k;
      }
      else
        k = next[k];
    }
    // kmp 算法
    k = index;
    j = 0;
    while(p_str[k]!='\0')
    {
      if(j==0 || p_str[k]==str[j])
      {
        k++;
        j++;
      }
      else
      {
        j = next[j];// 消除指针回溯
      }
      if(str[j] == '\0')//匹配成功
        return k-j;
    }
    return npos;
  }
  int MyString::find(const MyString& str,size_t index)
  {
//    if(this == &str)
//    {
//      MyString other(*this);
//      find(other,index);
//    }
    assert(NULL!=str && index<strLength);
    // kmp 中的getnext函数
 
    size_t next[str.strLength+2];
    size_t j,k;
    next[0] = npos;
    j = 0;
    k = npos;
    while(j<str.strLength)
    {
      if(k==npos || str.p_str[j]==str.p_str[k])
      {
        j++;
        k++;
        next[j] = k;
      }
      else
        k = next[k];
    }
    int i;
    for(i=1;i<=j;i++)
      cout << next[i] << ",";
    // kmp 算法
    k = index;
    j = 0;
    while(p_str[k]!='\0')
    {
      if(j==0 || p_str[k]==str.p_str[j])
      {
        k++;
        j++;
      }
      else
      {
        j = next[j];// 消除指针回溯
      }
      if(str.p_str[j] == '\0')//匹配成功,不知道为什么调用自身的str[]重载总是报错的
        return k-j;
    }
    if(str.p_str[j] == '\0')// 同一个字符串
      return k-j;
    return npos;
  }
  int MyString::find(const char ch,size_t index)
  {
    assert(NULL!=ch && index<strLength);
    for(size_t i=index;i<strLength;i++)
    {
      if(p_str[i] == ch)
        return i;
    }
    return npos;
  }

(3)测试函数main.cpp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "MyString.h"
#include <iostream>
using namespace std;
 
int main()
{
  int n;
  int choose = 1;
  int p,l;
  char cs[100];
  MyString s1;
  MyString s2("hello");
  MyString s3 = "HELLO";
  cout << "***** welcome *****\n";
  cout << "******* MADE BY zyp **********\n";
  cout << "s1= " << s1 << "s2= " << s2 << "s3= " << s3 << endl;
  cout << "请输入一个长度小于100的字符串:例如world\n";
  cin >> s1;
  s1 = s1;
  //s1 = s1+s1;
  s1 += s1;
  MyString s4(s1);
  s4.append(s1);
  s2.insert(2,s3);
  s1.erase(4,4);
  s1.assign(s2,1,7);
  cout << "s1= " << s1 << "s2= " << s2 << "s3= " << s3 << "s4= " << s4 << endl;
  s2 = s4.substr(2,7);
  cout << "s4[3]= " << s4[3] << s4.length() << (s1>=s2) << "s4.substr() " << s2 << endl;
  cout << "s1.find_first_of(beLE,2):" << s1.find_first_of("beLE",2) << ",s1.find_first_of(a,3):" << s1.find_first_of('a',3) << ",s1.find_first_of(s3,2):" << s1.find_first_of(s3,2) << endl;
  MyString s5(5,'b');
  s5 += s5;
  //s5.append(s5);// 不知道为什就是不能append
  cout << "s5 = " << s5 << "s5.find_first_not_of(aeHLEOl,2):" << s5.find_first_not_of("aeHLEOl",2) << "s5.find_first_not_of(aeHLEOl,0):" << s5.find_first_not_of("aeHLEOl") << endl;
  cout << "s5.find_first_not_of(s1,2):" << s5.find_first_not_of(s1,2) << "s5.find_first_not_of(b,2):" << s5.find_first_not_of('b',2) << endl;
  swap(s1,s5);
  s5.replace_all('a','J');
  MyString s6("LLO");
  cout << s1 << "," << s5 << "s5.find(LLO,0) " << s5.find("LLO",0) << "s5.find(s6,0) " << s5.find(s5) << endl;
  cout << npos << endl;
  return 0;
}

三:感悟

(1)耗时将近2天的实现了它,自己与其从中学到了很多,倒不如说是重新认识了string类;

(2)自己知道这个简单的string类,距离string源代码还差的很远很远;但是它帮助我更好的理解了string类,至少会简单的应用了。

(3)简单的实现了一下string类,参照的是STL源码,但是自己理解的还是不够深,难免有一些错误,请各位指教,万分感谢!

(4)下一步进军list

原文链接:http://blog.csdn.net/u010700335/article/details/40979037

延伸 · 阅读

精彩推荐
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30