string类详解(下)

打印 上一主题 下一主题

主题 896|帖子 896|积分 2688

4. string类的模仿实现

首先,我们先补充一下关于编码的知识:
  1. int main()
  2. {
  3.         char buff1[] = "abcd";
  4.         char buff2[] = "比特";
  5.        
  6.         cout << sizeof(buff1) << endl;
  7.         cout << sizeof(buff2) << endl;
  8.         cout << buff1 << endl;
  9.         cout << buff2 << endl;
  10.         return 0;
  11. }
复制代码



假如严格按照标准的话,我们应该要实现成 basic_string ,但是这样难度太大,要思量各种编码的拷贝,以是我们就实现的轻微简单一些,不要实现成模板了。
4.1 构造 + 析构

  1. //string::string()
  2. //{
  3. //        _str = new char[1]{ '\0' };
  4. //        _size = 0;
  5. //        _capacity = 0;
  6. //}
  7. string::string(const char* str)
  8.         :_size(strlen(str))
  9. {
  10.         _str = new char[_size + 1];
  11.         _capacity = _size;
  12.         strcpy(_str, str);
  13. }
  14. //s2(s1)
  15. string::string(const string& s)
  16. {
  17.         _str = new char[s._capacity + 1];
  18.         strcpy(_str, s._str);
  19.         _size = s._size;
  20.         _capacity = s._capacity;
  21. }
  22. string::~string()
  23. {
  24.         delete[] _str;
  25.         _str = nullptr;
  26.         _size = _capacity = 0;
  27. }
复制代码
4.2 c_str

  1. const char* string::c_str() const
  2. {
  3.         return _str;
  4. }
复制代码
4.3 下标遍历

  1. size_t string::size() const
  2. {
  3.         return _size;
  4. }
  5. char& string::operator[](size_t pos)
  6. {
  7.         assert(pos < _size);
  8.         return _str[pos];
  9. }
复制代码
  1. const char& string::operator[](size_t pos) const
  2. {
  3.         assert(pos < _size);
  4.         return _str[pos];
  5. }
复制代码
4.4 迭代器

  1. string::iterator string::begin()
  2. {
  3.         return _str;
  4. }
  5. string::iterator string::end()
  6. {
  7.         return _str + _size;
  8. }
复制代码

  1. string::const_iterator string::begin() const
  2. {
  3.         return _str;
  4. }
  5. string::const_iterator string::end() const
  6. {
  7.         return _str + _size;
  8. }
复制代码
4.5 插入

  1. void string::reserve(size_t n)
  2. {
  3.         if (n > _capacity)
  4.         {
  5.                 char* tmp = new char[n + 1];
  6.                 strcpy(tmp, _str);
  7.                 delete[] _str;
  8.                 _str = tmp;
  9.                 _capacity = n;
  10.         }
  11. }
  12. void string::push_back(char ch)
  13. {
  14.         if (_size == _capacity)
  15.         {
  16.                 size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;
  17.                 reserve(newcapacity);
  18.         }
  19.         _str[_size] = ch;
  20.         _str[_size + 1] = '\0';
  21.         ++_size;
  22. }
  23. //"hello"  "xxxxxxxxxxxxx"
  24. void string::append(const char* str)
  25. {
  26.         size_t len = strlen(str);
  27.         if (_size + len > _capacity)
  28.         {
  29.                 reserve(_size + len);
  30.         }
  31.         strcpy(_str + _size, str);
  32.         _size += len;
  33. }
  34. string& string::operator+=(char ch)
  35. {
  36.         push_back(ch);
  37.         return *this;
  38. }
  39. string& string::operator+=(const char* str)
  40. {
  41.         append(str);
  42.         return *this;
  43. }
复制代码


  1. void string::insert(size_t pos, char ch)
  2. {
  3.         assert(pos <= _size);
  4.         if (_size == _capacity)
  5.         {
  6.                 size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;
  7.                 reserve(newcapacity);
  8.         }
  9.         /*int end = _size;
  10.         while (end >= (int)pos)
  11.         {
  12.                 _str[end + 1] = _str[end];
  13.                 --end;
  14.         }*/
  15.         size_t end = _size + 1;
  16.         while (end > pos)
  17.         {
  18.                 _str[end] = _str[end - 1];
  19.                 --end;
  20.         }
  21.         _str[pos] = ch;
  22.         ++_size;
  23. }
复制代码


  1. void string::insert(size_t pos, const char* str)
  2. {
  3.         assert(pos <= _size);
  4.         size_t len = strlen(str);
  5.         if (_size + len > _capacity)
  6.         {
  7.                 reserve(_size + len);
  8.         }
  9.         /*int end = _size;
  10.         while (end >= (int)pos)
  11.         {
  12.                 _str[end + len] = _str[end];
  13.                 --end;
  14.         }*/
  15.         size_t end = _size + len;
  16.         while (end > pos + len - 1)
  17.         {
  18.                 _str[end] = _str[end - len];
  19.                 --end;
  20.         }
  21.         memcpy(_str + pos, str, len);
  22.         _size += len;
  23. }
复制代码
4.6 删除


  1. const size_t string::npos = -1;
  2. void string::erase(size_t pos, size_t len)
  3. {
  4.         assert(pos < _size);
  5.         //len 大于等于后面字符个数时,有多少删多少
  6.         if (len >= _size - pos)
  7.         {
  8.                 _str[pos] = '\0';
  9.                 _size = pos;
  10.         }
  11.         else
  12.         {
  13.                 strcpy(_str + pos, _str + pos + len);
  14.                 _size -= len;
  15.         }
  16. }
复制代码
4.7 查找

  1. size_t string::find(char ch, size_t pos)
  2. {
  3.         for (size_t i = pos; i < _size; i++)
  4.         {
  5.                 if (_str[i] == ch)
  6.                 {
  7.                         return i;
  8.                 }
  9.         }
  10.         return npos;
  11. }
  12. size_t string::find(const char* str, size_t pos)
  13. {
  14.         char* p = strstr(_str + pos, str);
  15.         return p - _str;
  16. }
复制代码
4.8 赋值


  1. //s1 = s3
  2. //s1 = s1
  3. string& string::operator=(const string& s)
  4. {
  5.         if (this != &s)
  6.         {
  7.                 char* tmp = new char[s._capacity + 1];
  8.                 strcpy(tmp, s._str);
  9.                 delete[] _str;
  10.                 _str = tmp;
  11.                 _size = s._size;
  12.                 _capacity = s._capacity;
  13.         }
  14.         return *this;
  15. }
复制代码
4.9 交换


  1. //s1.swap(s3)
  2. void string::swap(string& s)
  3. {
  4.         std::swap(_str, s._str);
  5.         std::swap(_size, s._size);
  6.         std::swap(_capacity, s._capacity);
  7. }
复制代码
4.10 提取子串


  1. string string::substr(size_t pos, size_t len)
  2. {
  3.         //len大于后面剩余字符,有多少取多少
  4.         if (len > _size - pos)
  5.         {
  6.                 string sub(_str + pos);
  7.                 return sub;
  8.         }
  9.         else
  10.         {
  11.                 string sub;
  12.                 sub.reserve(len);
  13.                 for (size_t i = 0; i < len; i++)
  14.                 {
  15.                         sub += _str[pos + i];
  16.                 }
  17.                 return sub;
  18.         }
  19. }
复制代码
4.11 比力巨细

  1. bool string::operator<(const string& s) const
  2. {
  3.         return strcmp(_str, s._str) < 0;
  4. }
  5. bool string::operator>(const string& s) const
  6. {
  7.         return !(*this <= s);
  8. }
  9. bool string::operator<=(const string& s) const
  10. {
  11.         return *this < s || *this == s;
  12. }
  13. bool string::operator>=(const string& s) const
  14. {
  15.         return !(*this < s);
  16. }
  17. bool string::operator==(const string& s) const
  18. {
  19.         return strcmp(_str, s._str) == 0;
  20. }
  21. bool string::operator!=(const string& s) const
  22. {
  23.         return !(*this == s);
  24. }
复制代码
4.12 流插入 && 流提取

  1. void string::clear()
  2. {
  3.         _str[0] = '\0';
  4.         _size = 0;
  5. }
  6. //一个字符一个字符放入str里,会有很多次扩容,可以优化
  7. //istream& operator>> (istream& is, string& str)
  8. //{
  9. //        str.clear();
  10. //        //流提取(>>)提取不了空格和换行,istream里的函数get()可以
  11. //        char ch = is.get();
  12. //        while (ch != ' ' && ch != '\n')
  13. //        {
  14. //                str += ch;
  15. //                ch = is.get();
  16. //        }
  17. //        return is;
  18. //}
  19. istream& operator>> (istream& is, string& str)
  20. {
  21.         str.clear();
  22.         char buff[128];
  23.         int i = 0;
  24.         char ch = is.get();
  25.         while (ch != ' ' && ch != '\n')
  26.         {
  27.                 buff[i++] = ch;
  28.                 // 0 - 126
  29.                 if (i == 127)
  30.                 {
  31.                         buff[i] = '\0';
  32.                         str += buff;
  33.                         i = 0;
  34.                 }
  35.                 ch = is.get();
  36.         }
  37.         if (i != 0)
  38.         {
  39.                 buff[i] = '\0';
  40.                 str += buff;
  41.         }
  42.         return is;
  43. }
  44. ostream& operator<< (ostream& os, const string& str)
  45. {
  46.         for (size_t i = 0; i < str.size(); i++)
  47.         {
  48.                 os << str[i];
  49.         }
  50.         return os;
  51. }
复制代码
5. 现代版写法的String类

我们之前写的拷贝构造和赋值运算符重载是传统写法,其实另有现代写法:

  1. //现代写法(让别人干活,交换)
  2. //s2(s1)
  3. string::string(const string& s)
  4. {
  5.         string tmp(s._str);
  6.         /*std::swap(tmp._str, _str);
  7.         std::swap(tmp._size, _size);
  8.         std::swap(tmp._capacity, _capacity);*/
  9.        
  10.         //这个是我们写的string类里的交换函数
  11.         swap(tmp);
  12. }
复制代码


  1. /*string& string::operator=(const string& s)
  2. {
  3.         if (this != &s)
  4.         {
  5.                 string tmp(s._str);
  6.                 swap(tmp);
  7.         }
  8.         return *this;
  9. }*/
  10. //s1 = s3
  11. string& string::operator=(string tmp)
  12. {
  13.         swap(tmp);
  14.         return *this;
  15. }
复制代码
5.1 完整代码

  1. //string.h
  2. #include <iostream>
  3. #include <assert.h>
  4. using namespace std;
  5. namespace bit
  6. {
  7.         class string
  8.         {
  9.         public:
  10.                 typedef char* iterator;
  11.                 typedef const char* const_iterator;
  12.                 iterator begin();
  13.                 iterator end();
  14.                 const_iterator begin() const;
  15.                 const_iterator end() const;
  16.                 //string();
  17.                 string(const char* str = "");
  18.                 string(const string& s);
  19.                 //string& operator=(const string& s);
  20.                 string& operator=(string tmp);
  21.                 ~string();
  22.                
  23.                 const char* c_str() const;
  24.                
  25.                 size_t size() const;
  26.                 char& operator[](size_t pos);
  27.                 const char& operator[](size_t pos) const;
  28.                 void reserve(size_t n);
  29.                 void push_back(char ch);
  30.                 void append(const char* str);
  31.                 string& operator+=(char ch);
  32.                 string& operator+=(const char* str);
  33.                 void insert(size_t pos, char ch);
  34.                 void insert(size_t pos, const char* str);
  35.                 void erase(size_t pos = 0, size_t len = npos);
  36.                 size_t find(char ch, size_t pos = 0);
  37.                 size_t find(const char* str, size_t pos =  0);
  38.                 void swap(string& s);
  39.                 string substr(size_t pos = 0, size_t len = npos);
  40.                 bool operator<(const string& s) const;
  41.                 bool operator>(const string& s) const;
  42.                 bool operator<=(const string& s) const;
  43.                 bool operator>=(const string& s) const;
  44.                 bool operator==(const string& s) const;
  45.                 bool operator!=(const string& s) const;
  46.                 void clear();
  47.         private:
  48.                 //char _buff[16];
  49.                 char* _str = nullptr;
  50.                 size_t _size = 0;
  51.                 size_t _capacity = 0;
  52.                 const static size_t npos;
  53.                
  54.                 //特例,const静态成员变量只有整型可以这样声明定义(了解即可,不建议这样写)
  55.                 //const static size_t npos = -1;
  56.                
  57.                 //不支持
  58.                 //const static double N = 2.2;
  59.         };
  60.         istream& operator>> (istream& is, string& str);
  61.         ostream& operator<< (ostream& os, const string& str);
  62. }
复制代码
  1. //string.cpp
  2. #include "string.h"
  3. namespace bit
  4. {
  5.         const size_t string::npos = -1;
  6.         //string::string()
  7.         //{
  8.         //        _str = new char[1]{ '\0' };
  9.         //        _size = 0;
  10.         //        _capacity = 0;
  11.         //}
  12.         string::iterator string::begin()
  13.         {
  14.                 return _str;
  15.         }
  16.         string::iterator string::end()
  17.         {
  18.                 return _str + _size;
  19.         }
  20.         string::const_iterator string::begin() const
  21.         {
  22.                 return _str;
  23.         }
  24.         string::const_iterator string::end() const
  25.         {
  26.                 return _str + _size;
  27.         }
  28.         string::string(const char* str)
  29.                 :_size(strlen(str))
  30.         {
  31.                 _str = new char[_size + 1];
  32.                 _capacity = _size;
  33.                 strcpy(_str, str);
  34.         }
  35.         //传统写法(实在人)
  36.         //s2(s1)
  37.         /*string::string(const string& s)
  38.         {
  39.                 _str = new char[s._capacity + 1];
  40.                 strcpy(_str, s._str);
  41.                 _size = s._size;
  42.                 _capacity = s._capacity;
  43.         }*/
  44.         //现代写法(让别人干活,交换)
  45.         //s2(s1)
  46.         string::string(const string& s)
  47.         {
  48.                 string tmp(s._str);
  49.                 /*std::swap(tmp._str, _str);
  50.                 std::swap(tmp._size, _size);
  51.                 std::swap(tmp._capacity, _capacity);*/
  52.                
  53.                 //这个是我们写的string类里的交换函数
  54.                 swap(tmp);
  55.         }
  56.         //s1 = s3
  57.         //s1 = s1
  58.         /*string& string::operator=(const string& s)
  59.         {
  60.                 if (this != &s)
  61.                 {
  62.                         char* tmp = new char[s._capacity + 1];
  63.                         strcpy(tmp, s._str);
  64.                         delete[] _str;
  65.                         _str = tmp;
  66.                         _size = s._size;
  67.                         _capacity = s._capacity;
  68.                 }
  69.                 return *this;
  70.         }*/
  71.         /*string& string::operator=(const string& s)
  72.         {
  73.                 if (this != &s)
  74.                 {
  75.                         string tmp(s._str);
  76.                         swap(tmp);
  77.                 }
  78.                 return *this;
  79.         }*/
  80.        
  81.         //s1 = s3
  82.         string& string::operator=(string tmp)
  83.         {
  84.                 swap(tmp);
  85.                 return *this;
  86.         }
  87.         string::~string()
  88.         {
  89.                 delete[] _str;
  90.                 _str = nullptr;
  91.                 _size = _capacity = 0;
  92.         }
  93.         const char* string::c_str() const
  94.         {
  95.                 return _str;
  96.         }
  97.         size_t string::size() const
  98.         {
  99.                 return _size;
  100.         }
  101.         char& string::operator[](size_t pos)
  102.         {
  103.                 assert(pos < _size);
  104.                 return _str[pos];
  105.         }
  106.         const char& string::operator[](size_t pos) const
  107.         {
  108.                 assert(pos < _size);
  109.                 return _str[pos];
  110.         }
  111.         void string::reserve(size_t n)
  112.         {
  113.                 if (n > _capacity)
  114.                 {
  115.                         char* tmp = new char[n + 1];
  116.                         strcpy(tmp, _str);
  117.                         delete[] _str;
  118.                         _str = tmp;
  119.                         _capacity = n;
  120.                 }
  121.         }
  122.         void string::push_back(char ch)
  123.         {
  124.                 /*if (_size == _capacity)
  125.                 {
  126.                         size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;
  127.                         reserve(newcapacity);
  128.                 }
  129.                 _str[_size] = ch;
  130.                 _str[_size + 1] = '\0';
  131.                 ++_size;*/
  132.                 insert(_size, ch);
  133.         }
  134.         //"hello"  "xxxxxxxxxxxxx"
  135.         void string::append(const char* str)
  136.         {
  137.                 /*size_t len = strlen(str);
  138.                 if (_size + len > _capacity)
  139.                 {
  140.                         reserve(_size + len);
  141.                 }
  142.                 strcpy(_str + _size, str);
  143.                 _size += len;*/
  144.                 insert(_size, str);
  145.         }
  146.         string& string::operator+=(char ch)
  147.         {
  148.                 push_back(ch);
  149.                 return *this;
  150.         }
  151.         string& string::operator+=(const char* str)
  152.         {
  153.                 append(str);
  154.                 return *this;
  155.         }
  156.         void string::insert(size_t pos, char ch)
  157.         {
  158.                 assert(pos <= _size);
  159.                 if (_size == _capacity)
  160.                 {
  161.                         size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;
  162.                         reserve(newcapacity);
  163.                 }
  164.                 /*int end = _size;
  165.                 while (end >= (int)pos)
  166.                 {
  167.                         _str[end + 1] = _str[end];
  168.                         --end;
  169.                 }*/
  170.                 size_t end = _size + 1;
  171.                 while (end > pos)
  172.                 {
  173.                         _str[end] = _str[end - 1];
  174.                         --end;
  175.                 }
  176.                 _str[pos] = ch;
  177.                 ++_size;
  178.         }
  179.         void string::insert(size_t pos, const char* str)
  180.         {
  181.                 assert(pos <= _size);
  182.                 size_t len = strlen(str);
  183.                 if (_size + len > _capacity)
  184.                 {
  185.                         reserve(_size + len);
  186.                 }
  187.                 /*int end = _size;
  188.                 while (end >= (int)pos)
  189.                 {
  190.                         _str[end + len] = _str[end];
  191.                         --end;
  192.                 }*/
  193.                 size_t end = _size + len;
  194.                 while (end > pos + len - 1)
  195.                 {
  196.                         _str[end] = _str[end - len];
  197.                         --end;
  198.                 }
  199.                 memcpy(_str + pos, str, len);
  200.                 _size += len;
  201.         }
  202.         void string::erase(size_t pos, size_t len)
  203.         {
  204.                 assert(pos < _size);
  205.                 //len 大于等于后面字符个数时,有多少删多少
  206.                 if (len >= _size - pos)
  207.                 {
  208.                         _str[pos] = '\0';
  209.                         _size = pos;
  210.                 }
  211.                 else
  212.                 {
  213.                         strcpy(_str + pos, _str + pos + len);
  214.                         _size -= len;
  215.                 }
  216.         }
  217.         size_t string::find(char ch, size_t pos)
  218.         {
  219.                 for (size_t i = pos; i < _size; i++)
  220.                 {
  221.                         if (_str[i] == ch)
  222.                         {
  223.                                 return i;
  224.                         }
  225.                 }
  226.                 return npos;
  227.         }
  228.         size_t string::find(const char* str, size_t pos)
  229.         {
  230.                 char* p = strstr(_str + pos, str);
  231.                 return p - _str;
  232.         }
  233.         //s1.swap(s3)
  234.         void string::swap(string& s)
  235.         {
  236.                 std::swap(_str, s._str);
  237.                 std::swap(_size, s._size);
  238.                 std::swap(_capacity, s._capacity);
  239.         }
  240.         string string::substr(size_t pos, size_t len)
  241.         {
  242.                 //len大于后面剩余字符,有多少取多少
  243.                 if (len > _size - pos)
  244.                 {
  245.                         string sub(_str + pos);
  246.                         return sub;
  247.                 }
  248.                 else
  249.                 {
  250.                         string sub;
  251.                         sub.reserve(len);
  252.                         for (size_t i = 0; i < len; i++)
  253.                         {
  254.                                 sub += _str[pos + i];
  255.                         }
  256.                         return sub;
  257.                 }
  258.         }
  259.         bool string::operator<(const string& s) const
  260.         {
  261.                 return strcmp(_str, s._str) < 0;
  262.         }
  263.         bool string::operator>(const string& s) const
  264.         {
  265.                 return !(*this <= s);
  266.         }
  267.         bool string::operator<=(const string& s) const
  268.         {
  269.                 return *this < s || *this == s;
  270.         }
  271.         bool string::operator>=(const string& s) const
  272.         {
  273.                 return !(*this < s);
  274.         }
  275.        
  276.         bool string::operator==(const string& s) const
  277.         {
  278.                 return strcmp(_str, s._str) == 0;
  279.         }
  280.         bool string::operator!=(const string& s) const
  281.         {
  282.                 return !(*this == s);
  283.         }
  284.         void string::clear()
  285.         {
  286.                 _str[0] = '\0';
  287.                 _size = 0;
  288.         }
  289.         //一个字符一个字符放入str里,会有很多次扩容,可以优化
  290.         //istream& operator>> (istream& is, string& str)
  291.         //{
  292.         //        str.clear();
  293.         //        //流提取(>>)提取不了空格和换行,istream里的函数get()可以
  294.         //        char ch = is.get();
  295.         //        while (ch != ' ' && ch != '\n')
  296.         //        {
  297.         //                str += ch;
  298.         //                ch = is.get();
  299.         //        }
  300.         //        return is;
  301.         //}
  302.         istream& operator>> (istream& is, string& str)
  303.         {
  304.                 str.clear();
  305.                 char buff[128];
  306.                 int i = 0;
  307.                 char ch = is.get();
  308.                 while (ch != ' ' && ch != '\n')
  309.                 {
  310.                         buff[i++] = ch;
  311.                         // 0 - 126
  312.                         if (i == 127)
  313.                         {
  314.                                 buff[i] = '\0';
  315.                                 str += buff;
  316.                                 i = 0;
  317.                         }
  318.                         ch = is.get();
  319.                 }
  320.                 if (i != 0)
  321.                 {
  322.                         buff[i] = '\0';
  323.                         str += buff;
  324.                 }
  325.                 return is;
  326.         }
  327.         ostream& operator<< (ostream& os, const string& str)
  328.         {
  329.                 for (size_t i = 0; i < str.size(); i++)
  330.                 {
  331.                         os << str[i];
  332.                 }
  333.                 return os;
  334.         }
  335. }
复制代码
  1. //Test.cpp
  2. #include "string.h"
  3. namespace bit
  4. {
  5.         void test_string1()
  6.         {
  7.                 string s1("hello world");
  8.                 cout << s1.c_str() << endl;
  9.                 for (size_t i = 0; i < s1.size(); i++)
  10.                 {
  11.                         s1[i]++;
  12.                 }
  13.                 for (size_t i = 0; i < s1.size(); i++)
  14.                 {
  15.                         cout << s1[i] << " ";
  16.                 }
  17.                 cout << endl;
  18.                 //封装:统一屏蔽了底层实现细节,提供了一种简单通用的访问容器的方式
  19.                 string::iterator it1 = s1.begin();
  20.                 while (it1 != s1.end())
  21.                 {
  22.                         cout << *it1 << " ";
  23.                         ++it1;
  24.                 }
  25.                 cout << endl;
  26.                 for (auto e : s1)
  27.                 {
  28.                         cout << e << " ";
  29.                 }
  30.                 cout << endl;
  31.                 string s2;
  32.                 cout << s2.c_str() << endl;
  33.                 const string s3("xxxxxxx");
  34.                 string::const_iterator it3 = s3.begin();
  35.                 while (it3 != s3.end())
  36.                 {
  37.                         //*it3 = 'y';//err
  38.                         cout << *it3 << " ";
  39.                         ++it3;
  40.                 }
  41.                 cout << endl;
  42.                 for (size_t i = 0; i < s3.size(); i++)
  43.                 {
  44.                         //s3[i]++;
  45.                         cout << s3[i] << " ";
  46.                 }
  47.                 cout << endl;
  48.         }
  49.         void test_string2()
  50.         {
  51.                 string s1("hello world");
  52.                 cout << s1.c_str() << endl;
  53.        
  54.                 s1.push_back('x');
  55.                 cout << s1.c_str() << endl;
  56.                
  57.                 s1.append("yyyyy");
  58.                 cout << s1.c_str() << endl;
  59.        
  60.                 s1 += 'z';
  61.                 s1 += "mmmmmm";
  62.                 cout << s1.c_str() << endl;
  63.         }
  64.         void test_string3()
  65.         {
  66.                 string s1("hello world");
  67.                 cout << s1.c_str() << endl;
  68.                 s1.insert(6, 'x');
  69.                 cout << s1.c_str() << endl;
  70.                 s1.insert(0, 'x');
  71.                 cout << s1.c_str() << endl;
  72.        
  73.                 string s2("hello world");
  74.                 cout << s2.c_str() << endl;
  75.                 s2.insert(6, "yyy");
  76.                 cout << s2.c_str() << endl;
  77.                 s2.insert(0, "yyy");
  78.                 cout << s2.c_str() << endl;
  79.                 string s3("hello world");
  80.                 cout << s3.c_str() << endl;
  81.                 //s3.erase(6, 10);
  82.                 s3.erase(6);
  83.                 cout << s3.c_str() << endl;
  84.                 string s4("hello world");
  85.                 cout << s4.c_str() << endl;
  86.                 s4.erase(6, 3);
  87.                 cout << s4.c_str() << endl;
  88.         }
  89.         void test_string4()
  90.         {
  91.                 string s1("hello world");
  92.                 cout << s1.find('o') << endl;
  93.                 cout << s1.find("wor") << endl;
  94.         }
  95.         void test_string5()
  96.         {
  97.                 string s1("hello world");
  98.                 string s2(s1);
  99.                 s1[0] = 'x';
  100.                 cout << s1.c_str() << endl;
  101.                 cout << s2.c_str() << endl;
  102.        
  103.                 string s3("yyyy");
  104.                 s1 = s3;
  105.                 cout << s1.c_str() << endl;
  106.                 cout << s3.c_str() << endl;
  107.        
  108.                 string s4("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
  109.                 s1 = s4;
  110.                 cout << s1.c_str() << endl;
  111.                 cout << s4.c_str() << endl;
  112.        
  113.                 s1 = s1;
  114.                 cout << s1.c_str() << endl;
  115.                 cout << s3.c_str() << endl;
  116.                
  117.                 std::swap(s1, s3);
  118.                 cout << s1.c_str() << endl;
  119.                 cout << s3.c_str() << endl;
  120.                 s1.swap(s3);
  121.                 cout << s1.c_str() << endl;
  122.                 cout << s3.c_str() << endl;
  123.         }
  124.         void test_string6()
  125.         {
  126.                 string url("https://gitee.com/ailiangshilove/cpp-class/blob/master/%E8%AF%BE%E4%BB%B6%E4%BB%A3%E7%A0%81/C++%E8%AF%BE%E4%BB%B6V6/string%E7%9A%84%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95%E5%8F%8A%E4%BD%BF%E7%94%A8/TestString.cpp");
  127.                 size_t pos1 = url.find(':');
  128.                 string url1 = url.substr(0, pos1 - 0);
  129.                 cout << url1.c_str() << endl;
  130.                 size_t pos2 = url.find('/', pos1 + 3);
  131.                 string url2 = url.substr(pos1 + 3, pos2 - (pos1 + 3));
  132.                 cout << url2.c_str() << endl;
  133.                 string url3 = url.substr(pos2 + 1);
  134.                 cout << url3.c_str() << endl;
  135.         }
  136.         void test_string7()
  137.         {
  138.                 //string s1("hello world");
  139.                 //cout << s1 << endl;
  140.                
  141.                 string s1;
  142.                 cin >> s1;
  143.                 cout << s1 << endl;
  144.         }
  145.         void test_string8()
  146.         {
  147.                 string s1("hello world");
  148.                 string s2(s1);
  149.                 cout << s1 << endl;
  150.                 cout << s2 << endl;
  151.                 string s3("xxxxxxxxxxxxxxxxxxxxxxxxx");
  152.                 s1 = s3;
  153.                 cout << s1 << endl;
  154.                 cout << s3 << endl;
  155.         }
  156. }
  157. int main()
  158. {
  159.         bit::test_string8();
  160.         return 0;
  161. }
复制代码
6. 写时拷贝(了解)

写时拷贝就是一种拖延症,是在浅拷贝的基础之上增长了引用计数的方式来实现的。
引用计数:用来记载资源使用者的个数。在构造时,将资源的计数给成1,每增长一个对象使用该资源,就给计数增长1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要开释资源,假如计数为1,阐明该对象时资源的末了一个使用者,将该资源开释;否则就不能开释,因为另有其他对象在使用该资源。

举个例子:
  1. void copy_on_write()
  2. {
  3.         //如果计数不等于1,再去做深拷贝
  4. }
  5. void string::push_back(char ch)
  6. {
  7.         //写时拷贝
  8.         copy_on_write();
  9.         /*if (_size == _capacity)
  10.         {
  11.                 size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;
  12.                 reserve(newcapacity);
  13.         }
  14.         _str[_size] = ch;
  15.         _str[_size + 1] = '\0';
  16.         ++_size;*/
  17.         insert(_size, ch);
  18. }
复制代码
可以用下面的代码来看是否是用了写时拷贝:
  1. void test_string9()
  2. {
  3.         std::string s1("hello world");
  4.         std::string s2(s1);
  5.         cout << (void*)s1.c_str() << endl;
  6.         cout << (void*)s2.c_str() << endl;
  7. }
复制代码
Windows的VS下没有用写时拷贝,而Linux的g++就使用了写时拷贝。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户云卷云舒

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表