String:利用引用计数进行实现

利用引用计数的实现方式

 

#include <iostream>
#include <cstring>
#include <iomanip>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
using  namespace std;

class StringBuf{
     public:
        StringBuf():buf( 0),len( 0),used( 0),refs( 1){}
//         StringBuf(int n):buf(new char[n]),len(1.5*n),used(0),refs(1){ }
        StringBuf( int n):buf( 0),len( 0),used( 0),refs( 1){
            Reserve(n);
        }
        StringBuf( const StringBuf& other,size_t n= 0);
        ~StringBuf(){delete[] buf;}
         void Reserve(size_t n);
         char *buf;
        size_t len;
        size_t used;
        unsigned refs;
     private:
//         StringBuf(const StringBuf&);
        StringBuf&  operator=( const StringBuf&);
};
StringBuf::StringBuf( const StringBuf& other,size_t n):
    buf( 0),len( 0),used( 0),refs( 1){
        Reserve(max(other.len,n));
        strncpy(buf,other.buf,other.used);
        used=other.used;
    }
void StringBuf::Reserve(size_t n){
     if(len<n){
        size_t needed=max<size_t>(len* 1.5,n);
        size_t newlen=needed? 4*((needed- 1)/ 4+ 1): 0;
         char *newbuf=newlen? new  char[newlen]: 0;
         if(buf){
            strncpy(newbuf,buf,used);
        }
        delete[] buf;
        buf=newbuf;
        len=newlen;
    }
}
class String{
    friend istream&  operator>>(istream&,String&);
    friend ostream&  operator<<(ostream&, const String&);
    friend String  operator+( const String&, const String&);
    friend String  operator+( const String&, const  char*);
     public:
        String();
        String( int, char);
        String( const  char*);
        String( const String&);
        ~String();
        String&  operator=( const String&);
        String&  operator=( const  char*);
        String&  operator+=( const String&);
        String&  operator+=( const  char*);
        String&  operator+=( const  char&);
         bool  operator==( const String &) const;
         bool  operator!=( const String &) const;
         bool  operator>( const String &) const;
         bool  operator>=( const String &) const;
         bool  operator<( const String &) const;
         bool  operator<=( const String &) const;
         bool  operator==( const  char*) const;
         bool  operator!=( const  char*) const;
         bool  operator>( const  char*) const;
         bool  operator>=( const  char*) const;
         bool  operator<( const  char*) const;
         bool  operator<=( const  char*) const;
         charoperator[](size_t );
         const  char  operator[](size_t) const;
        size_t size() const{
             return data_->used;
        }
         char* c_str();
//     private:
         void AboutToModify(size_t n, bool bUnshareable= false);
         const  static size_t Unshareable;
        StringBuf* data_;
};
const size_t String::Unshareable= 100;
String::~String(){
     if(data_->refs==Unshareable||--data_->refs< 1)
        delete data_;
}
String::String():data_( new StringBuf){}
String::String( int n, char ch):data_( new StringBuf(n)){
     for( int i= 0;i<n;i++)
        data_->buf[i]=ch;
    data_->used=n;
}
String::String( const  char*str){
     if(!str)
        data_= new StringBuf();
     else{
        size_t n=strlen(str);
        data_= new StringBuf(n);
        strncpy(data_->buf,str,n);
        data_->used=n;
    }
}
String::String( const String& other){
     if(other.data_->refs!=Unshareable){
        data_=other.data_;
        ++data_->refs;
    }
     else{
        data_= new StringBuf(*other.data_);
    }
}
void String::AboutToModify(size_t n, bool markUnshareable){
     if(data_->refs> 1&&data_->refs!=Unshareable){
        StringBuf* newdata= new StringBuf(*data_,n);
        --data_->refs;
        data_=newdata;
    }
     else{
        data_->Reserve(n);
    }
    data_->refs=markUnshareable?Unshareable: 1;
}
String& String:: operator=( const String& str){
     if( this!=&str){
     if(data_->refs==Unshareable||--data_->refs< 1)
        delete data_;
         if(str.data_->refs!=Unshareable){
            data_=str.data_;
            ++data_->refs;
        }
         else{
            data_= new StringBuf(*str.data_);
        }
    }
     return * this;
}
String& String:: operator=( const  char*str){
     if(!str) {
        data_=NULL;
    }
     else{
        size_t n=strlen(str);
        AboutToModify(n, false);
        strncpy(data_->buf,str,n);
        data_->used=n;
    }
     return * this;
}
String& String:: operator+=( const String& str){
     if(str.size()== 0)
         return * this;
    size_t n=str.size();
    AboutToModify(data_->used+n, false);
    strncpy(data_->buf+data_->used,str.data_->buf,n);
    data_->used+=n;
//     if(data_.refs==1){
//         data_.Reserve(data_->used+n);
//         strncpy(data_->buf+data_->used,str.data_->buf,n);
//         data_->used+=n;
//     }
//     else{
//         free();
//         StringBuf* tmp=new StringBuf(data_->used+n);
//         strncpy(tmp.buf,str.data_->buf,data_->used);
//         strncpy(tmp.buf+data_->used,str.data_->buf,n);
//         tmp.used=data_->used+n;
//         data_=tmp;
//     }
     return * this;
}
String& String:: operator+=( const  char *str){
     if(!str)
         return * this;
    size_t n=strlen(str);
    AboutToModify(data_->used+n, false);
    strncpy(data_->buf+data_->used,str,n);
        data_->used+=n;
//     if(data_.refs==1){
//         data_.Reserve(data_->used+n);
//         strncpy(data_->buf+data_->used,str,n);
//         data_->used+=n;
//     }
//     else{
//         free();
//         StringBuf* tmp=new StringBuf(data_->used+n);
//         strncpy(tmp.buf,str.data_->buf,data_->used);
//         strncpy(tmp.buf+data_->used,str,n);
//         tmp.used=data_->used+n;
//         data_=tmp;
//     }
     return * this;
}
String& String:: operator+=( const  char& c){
    AboutToModify(data_->used+ 1, false);
    data_->buf[data_->used++]=c;

//     if(data_.refs==1){
//         data_.Reserve(data_->used+1);
//         data_->buf[data_->used++]=c;
//     }
//     else{
//         free();
//         StringBuf* tmp=new StringBuf(data_->used+1);
//         strncpy(tmp.buf,str.data_->buf,data_->used);
//         tmp.buf[data_->used+1]=c;
//         tmp.used=data_->used+1;
//         data_=tmp;
//     }
}
bool String:: operator==( const String& str) const{
     if(data_->buf==str.data_->buf)
         return  true;
     else  if(data_->used==str.data_->used)
         return strncmp(data_->buf,str.data_->buf,data_->used)== 0? true: false;
     else
         return  false;
}
bool String:: operator!=( const String& str) const{
     return !(* this==str);
}
bool String:: operator>( const String& str) const{
     if(data_->buf==str.data_->buf)
         return  false;
     else  if(data_->used==str.data_->used)
         return strncmp(data_->buf,str.data_->buf,data_->used)> 0? true: false;
     else{
         int n=min(data_->used,str.data_->used);
         int cmp=strncmp(data_->buf,str.data_->buf,n);
         if(cmp== 0)
             return data_->used<str.data_->used;
         else
             return cmp> 0;
    }
}
bool String:: operator>=( const String&str) const{
     return * this==str||* this>str;
}
bool String:: operator<( const String& str) const{
     return !(* this>str);
}
bool String:: operator<=( const String& str) const{
     return * this==str||* this<str;
}
bool String:: operator==( const  char *str) const{
    size_t n=strlen(str);
     if(data_->used==n)
         return strncmp(data_->buf,str,data_->used)== 0? true: false;
     else
         return  false;
}
bool String:: operator!=( const  char *str) const{
     return !(* this==str);
}
bool String:: operator>( const  char* str) const{
    size_t sz=strlen(str);
     if(data_->used==sz)
         return strncmp(data_->buf,str,data_->used)> 0? true: false;
     else{
         int n=min(data_->used,sz);
         int cmp=strncmp(data_->buf,str,n);
         if(cmp== 0)
             return data_->used<sz;
         else
             return cmp> 0;
    }
}
bool String:: operator>=( const  char* str) const {
     return * this==str||* this>str;
}
bool String:: operator<( const  char* str) const {
     return !(* this>str);
}
bool String:: operator<=( const  char* str) const {
     return * this==str||* this<str;
}
char& String:: operator[](size_t n){
    AboutToModify(data_->len, false);
     return data_->buf[n];
}
const  char String:: operator[](size_t n) const{
     return data_->buf[n];
}
String  operator+( const String& str1, const String& str2){
     if(str1.data_->used== 0&&str2.data_->used== 0)
         return String();
     else  if(str1.data_->used== 0&&str2.data_->used!= 0){
         return String(str2);
    }
     else  if(str1.data_->used!= 0&&str2.data_->used== 0){
         return String(str1);
    }
     else{
        String newstr;
        newstr.AboutToModify(str1.data_->used+str1.data_->used, false);
        strncpy(newstr.data_->buf,str1.data_->buf,str1.data_->used);
        strncpy(newstr.data_->buf+str1.data_->used,str2.data_->buf,str2.data_->used);
        newstr.data_->used=str1.data_->used+str2.data_->used;
         return newstr;
    }

}

String  operator+( const String&str1, const  char*str2) {
    size_t len=strlen(str2);
     if(str1.data_->used== 0&&len== 0)
         return String();
     else  if(str1.data_->used== 0&&len!= 0){
         return String(str2);
    }
     else  if(str1.data_->used!= 0&&len== 0){
         return String(str1);
    }
     else{
        String newstr;
        newstr.AboutToModify(str1.data_->used+len, false);
        strncpy(newstr.data_->buf,str1.data_->buf,str1.data_->used);
        strncpy(newstr.data_->buf+str1.data_->used,str2,len);
        newstr.data_->used=str1.data_->used+len;
         return newstr;
    }
}
istream&  operator>>(istream&  is,String& str){
     const  int limit_string_used= 4096;
     char inBuf[limit_string_used];
     is>>setw(limit_string_used)>>inBuf;
    str=inBuf;
     return  is;
}
ostream&  operator<<(ostream& os, const String& str){
     for( int i= 0;i<str.data_->used;i++)
        os<<str.data_->buf[i];
     return os;
}
int main1()
{
     int aCnt =  0, eCnt =  0, iCnt =  0, oCnt =  0, uCnt =  0,
        theCnt =  0, itCnt =  0, wdCnt =  0, notVowel =  0;
     //  为了使用 operator==( const char* )
    
//  我们并不定义 The( "The" )和 It( "It" )
    String buf, the(  " the " ), it(  " it " );
     //  调用 operator>>( istream&, String& )
     while ( cin >> buf ) {
        ++wdCnt;
         //  调用 operator<<( ostream&, const String& )
        cout << buf <<  '   ';
         if ( wdCnt %  12 ==  0 )
            cout << endl;
         //  调用 String::operator==(const String&) and
        
//
         if ( buf == the || buf ==  " The " )
            ++theCnt;
         if ( buf == it || buf ==  " It " )
                ++itCnt;
         //  调用 String::size()
         for (  int ix =  0; ix < buf.size(); ++ix )
        {
             //  调用 String::operator[](int)
             switch( buf[ ix ] )
            {
                 case  ' a 'case  ' A ': ++aCnt;
                                     break;
                 case  ' e 'case  ' E ': ++eCnt;
                                     break;
                 case  ' i 'case  ' I ': ++iCnt;
                                     break;
                 case  ' o 'case  ' O ': ++oCnt;
                                     break;
                 case  ' u 'case  ' U ': ++uCnt;
                                     break;
                 default: ++notVowel;  break;
            }
        }
    }
     //  调用 operator<<( ostream&, const String& )
    cout <<  " \n\n "
        << " Words read:  " << wdCnt <<  " \n\n "
        << " the/The:  " << theCnt <<  ' \n '
        << " it/It:  " << itCnt <<  " \n\n "
        << " non-vowels read:  " << notVowel <<  " \n\n "
        << " a:  " << aCnt <<  ' \n '
        << " e:  " << eCnt <<  ' \n '
        << " i:  " << iCnt <<  ' \n '
        << " o:  " << oCnt <<  ' \n '
        << " u:  " << uCnt << endl;

    String a= " hello ";
    String b= " world ";
    String c=a+b;
    cout<<c<<endl;

     return  0;

}

int main(){
    String s= " abc ";
    cout<<s.data_->refs<<endl;
    String s2= " abc ";
    cout<<s2.data_->refs<<endl;
    s+= " dd ";
    String s3=s+s2;
    cout<<s3<<endl;
    cout<<s3.data_->refs<<endl;
    String s4(s3);
    cout<<s4<<endl;
    cout<<s4.data_->refs<<endl;
    cout<<s3.data_->refs<<endl;
    s4[ 1]= ' x ';
    cout<<s4<<endl;
    cout<<s4.data_->refs<<endl;
    cout<<s3.data_->refs<<endl;
    String s5(s4);
    cout<<s5<<endl;
    cout<<s5.data_->refs<<endl;
    cout<<s4.data_->refs<<endl;
    cout<<s3<<endl;
    cout<<s3.data_->refs<<endl;
}

转载于:https://www.cnblogs.com/xkfz007/archive/2012/08/24/2653808.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值