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;
}
posted @ 2012-08-24 10:42  Mr.Rico  阅读(333)  评论(0编辑  收藏  举报