zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    如何使用Total Recorder录制软件发出的声音
    火狐浏览器Firefox如何使用插件,火狐有哪些好用的插件
    [Tools] Create a Simple CLI Tool in Node.js with CAC
    [Unit Testing] Mock a Node module's dependencies using Proxyquire
    [SCSS] Create a gradient with a Sass loop
    [Algorithm] Heap data structure and heap sort algorithm
    [Debug] Diagnose a Slow Page Using Developer Tools
    [Tools] Deploy a Monorepo to Now V2
    [PWA] Add Push Notifications to a PWA with React in Chrome and on Android
    [Algorithms] Using Dynamic Programming to Solve longest common subsequence problem
  • 原文地址:https://www.cnblogs.com/xkfz007/p/2653808.html
Copyright © 2011-2022 走看看