【C++】深浅コピー実装Stringクラス

5981 ワード

深浅コピーとは?
文字列char*str 1=「hello」を定義します.
文字列char*str 2とstr 1を定義するデータは同じで、この場合は2つに分けられます.
  • str 1とstr 2のデータと空間は同じであり、str 2はstr 1のアドレス空間を指す.
  • str 2は別の空間を開き、str 1のデータをstr 2にコピーします.すなわち、str 1とstr 2のデータは同じで、指向するアドレスは違います.

  • 1つ目は浅いコピー、2つ目は深いコピーと呼ばれます
    C++では、浅いコピーを使用すると深刻なコード事故が発生しやすい---メモリ漏れ
    str 1とstr 2は同じアドレス空間を指し、構造関数はシステムが自動的に生成して呼び出され、空き構造が2回発生する場合がある.
    次に、濃淡コピーの伝統的な書き方と現代的な書き方を用いてStringクラスを実現します.
    従来の書き方と現代の書き方の主な違いは、コピー構造関数と賦値オペレータのリロード関数の書き方が異なることであり、以下の通りである.
    コピーコンストラクション関数の書き方:
     void Swap(String& s)
        {
          swap(_str,s._str);
          swap(_size,s._size);
          swap(_capacity,s._capacity);
        }
        //     
         String(const String& s)
             :_str(new char[strlen(s._str)+1])
           {
             strcpy(_str,s._str);
           }
        //    
        String(const String& s)
          :_str(NULL)
        {
          String tmp(s._str);
          Swap(tmp);
        }
    

    代入演算子のリロード関数の異なる書き方:
         
        String& operator=(const String& s){
          if(this!=&s){
            String tmp(s._str);
            swap(_str,tmp._str);
          }
          return *this;
        }
               
        String& operator=(String s){
          if(this!=&s){
            Swap(s);
            return *this;
          }
        }
        //    
        //s1=s2,s2       s1   
        //       ,          ,      
        //      
            String& operator=(const String& s)
            {
              if(this!=&s){
                delete[] _str;
                char* tmp=new char[strlen(s._str)+1];
                strcpy(tmp,s._str);
                _str=tmp;
              }
              return *this;
            }

    すべてのコード実装:
    #pragma once
    #include
    #include
    #include
    using namespace std;
    //1.     
    //2.                 
    class String{
      public:
        String(const char* str)
          :_size(strlen(str))
           ,_capacity(_size)
      {
        _str=new char[_size+1];
        strcpy(_str,str);
      }
        void Swap(String& s)
        {
          swap(_str,s._str);
          swap(_size,s._size);
          swap(_capacity,s._capacity);
        }
    
        //s1(s);   
            String(const String& s)
             :_str(new char[strlen(s._str)+1])
           {
             strcpy(_str,s._str);
           }
        //    
      /*  String(const String& s)
          :_str(NULL)
        {
          String tmp(s._str);
          Swap(tmp);
        }
            
        String& operator=(const String& s){
          if(this!=&s){
            String tmp(s._str);
            swap(_str,tmp._str);
          }
          return *this;
        }*/
               
        String& operator=(String s){
          if(this!=&s){
            Swap(s);
            return *this;
          }
        }
        //s1=s2,s2       s1   
        //       ,          ,      
        //      
            /*String& operator=(const String& s)
            {
              if(this!=&s){
                delete[] _str;
                char* tmp=new char[strlen(s._str)+1];
                strcpy(tmp,s._str);
                _str=tmp;
              }
              return *this;
            }
    */
        ~String(){
          if(_str){
            delete[] _str;
            _str=NULL;
          }
        }
        void Expand(size_t n){
          if(n>_capacity){
            char* tmp=new char[n+1];
            strcpy(tmp,_str);
            delete[] _str;
            _str=tmp;
            _capacity=n;
          }
        }
        void PushBack(char ch){
          if(_size>=_capacity){
            Expand(2*_size); 
          }
          _str[_size]=ch;
          _str[_size+1]='\0';
          ++_size;
        }
        void Append(const char* str){//     
          size_t len=strlen(str);
          if(_size+len>=_capacity){
            Expand(_size+len);
          }
          strcpy(_str+_size,str);
          _size+=len;
        }
        void PopBack()
        {
          assert(_size);
          _str[_size--]='\0';
          --_size;
        }
        void Insert(size_t pos,char ch){
          assert(pos<=_size);
          if(_capacity==_size){
            Expand(2*_capacity);
          }
          size_t end=_size;
          while(end>=pos){
            _str[end+1]=_str[end];
            --end;
          }
          _str[pos]=ch;
          ++_size;
        }
        void Insert(size_t pos,const char* str){
          assert(pos<=_size);
          int len=strlen(str);
          if(_size+len>_capacity){
            Expand(_size+len);
          }
          for(int i=pos;i<_size _str="" for="" j="0;j<len;j++){" void="" erase="" pos="" n="" assert="" if="" strcpy="" size_t="" size="" return="" _size="" capacity="" _capacity="" bool="" empty="" char="" operator="" find="" ch="" count="0;" i="0;i<_size;i++){" str="" src="_str;" while="" const="" dest="str;" string="" tmp="" tmp.pushback="" this-="">PushBack(ch);
          return *this;
        }
        //s1+=s2
        String operator+=(const String& str){
          *this+=str._str;//s._str    ,       operator+= 
          return *this;
        }
        String operator+(const char* str){
          assert(str);
          String tmp(*this);
          tmp.Append(str);
          return tmp;
        }
        String& operator+=(char* str){
          this->Append(str);
          return *this;
        }
        int _strcmp(const char* str1,const char* str2){
          while(*str1&&*str2){
            if(*str1>*str2){
              return 1;
            }else if(*str1(const String& s)
        {
          if((_strcmp(_str,s._str))>0){
            return true;
          }else{
            return false;
          }
        }
          bool operator>=(const String& s)
          {
            if((_strcmp(_str,s._str))>=0){
              return true;
            }else{
              return false;
            }
          }
    
        //  C     
        char* c_str(){
          return _str;
        }
      private:
        char* _str;
        size_t _size;
        size_t _capacity;
    };
    void TestString(){
      String s1("hello");
     // cout<