利用引用计数的实现方式
#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;
char& operator[](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;
}
#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;
char& operator[](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;
}