亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++中sting類的簡單實(shí)現(xiàn)方法

 更新時(shí)間:2016年08月22日 09:23:12   作者:chentingting的小天地  
這篇文章主要介紹了C++中sting類的簡單實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下

String

在C++的學(xué)習(xí)生涯我中發(fā)現(xiàn)String類的功能十分強(qiáng)大,所以我們是很有必要模擬實(shí)現(xiàn)它的,況且在面試的時(shí)候模擬實(shí)現(xiàn)一個(gè)String類也是面試官經(jīng)常會考的,但是因?yàn)橥饨缫蛩氐南拗莆覀兪遣豢赡苣M的和庫里的string一致的(C++庫里的string功能更強(qiáng)大),所以今天我們只模擬實(shí)現(xiàn)string的基本功能-構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),析構(gòu)函數(shù),賦值運(yùn)算符重載,運(yùn)算符+=的重載,運(yùn)算符[]的重載,c_str(得到一個(gè)C風(fēng)格的字符指針,可操作字符串),Size,Push_Back,Insert(深拷貝),以及用寫時(shí)拷貝copy_on_write的方式實(shí)現(xiàn)基本的String類

深拷貝的方式

class String 
{ 
friend ostream &operator<<(ostream &os,String &s); 
public: 
String(const char *str=""); //全缺省的構(gòu)造函數(shù),解決空字符串的問題 
String(const String &ps); //深拷貝 
String &operator=(String s); 
String &operator+=(const char * s); 
const char *C_Str()const //得到C風(fēng)格的字符指針 
{ 
return _pstr; 
} 
char &operator[](size_t index) 
{ 
return _pstr[index]; 
} 
size_t Size()const 
{ 
return _size; 
} 
void PushBack(char c); 
String &Insert(size_t pos,const char *str); 
//String &operator=(String &s) 
//{ 
// cout<<"String &operator=(String &s)"<<endl; 
// if(this != &s) 
// { 
// delete[]_pstr; 
// _pstr=new char[strlen(s._pstr)+1]; 
// strcpy(_pstr,s._pstr); 
// } 
// return *this; 
//} 
~String() 
{ 
cout<<"~String()"<<endl; 
if(_pstr != NULL) 
{ 
delete[]_pstr; 
_pstr=NULL; 
_size=0; 
_capacity=0; 
} 
} 
private: 
void CheckCapacity(int count); 
private: 
int _size; 
int _capacity; 
char *_pstr; 
}; 
ostream &operator<<(ostream &os,String &s) 
{ 
os<<s._pstr; 
return os; 
} 
String::String(const char *str) 
:_size(strlen(str)) 
,_capacity(strlen(str)+1) 
,_pstr(new char[_capacity]) 
{ 
cout<<"String()"<<endl; 
strcpy(_pstr,str); 
} 
String::String(const String &ps) 
:_size(ps._size) 
,_capacity(strlen(ps._pstr)+1) 
,_pstr(new char[_capacity]) 
{ 
cout<<"String(const String &ps)"<<endl; 
strcpy(_pstr,ps._pstr); 
} 
String &String::operator=(String s) 
{ 
cout<<"String &operator=(String s)"<<endl; 
std::swap(_pstr,s._pstr); 
std::swap(_size,s._size); 
std::swap(_capacity,s._capacity); 
return *this; 
} 
void String::CheckCapacity(int count) 
{ 
if(_size+count >= _capacity) 
{ 
int _count=(2*_capacity)>(_capacity+count)?(2*_capacity):(_capacity+count); 
char *tmp=new char[_count]; 
strcpy(tmp,_pstr); 
delete[]_pstr; 
_pstr=tmp; 
_capacity=_count; 
} 
} 
void String::PushBack(char c) 
{ 
CheckCapacity(1); 
_pstr[_size++]=c; 
_pstr[_size]='\0'; 
} 
String &String::operator+=(const char * s) 
{ 
CheckCapacity(strlen(s)); 
while(*s) 
{ 
_pstr[_size++]=*s; 
s++; 
} 
_pstr[_size]='\0'; 
return *this; 
} 
String &String::Insert(size_t pos,const char *str) 
{ 
char *tmp=new char[strlen(_pstr+pos)]; 
strcpy(tmp,_pstr+pos); 
CheckCapacity(strlen(str)); 
while(*str) 
{ 
_pstr[pos++]=*str; 
str++; 
} 
strcpy(_pstr+pos,tmp); 
return *this; 
}

通過測試上述代碼可正常運(yùn)行,特別是在實(shí)現(xiàn)賦值運(yùn)算符重載的時(shí)候我們使用了兩種方式,值得一提的是應(yīng)用swap函數(shù)來實(shí)現(xiàn)賦值運(yùn)算符的重載(在傳參時(shí)不可以傳引用),因?yàn)閼?yīng)用swap函數(shù)實(shí)現(xiàn)是根據(jù)臨時(shí)變量的創(chuàng)建并且該臨時(shí)變量出作用域就會自動調(diào)用析構(gòu)函數(shù)銷毀(現(xiàn)代的方法)

測試深拷貝的方法

void text1() 
{ 
String str1("hello"); 
String str2(str1); 
String str3; 
str3=str1; 
cout<<str1<<endl; 
cout<<str2<<endl; 
cout<<str3<<endl; 
cout<<strlen(str1.C_Str())<<endl; //5 
str1[4]='w'; 
cout<<str1<<endl; //hellw 
} 
void text2() 
{ 
String str1("abcd"); 
cout<<str1<<endl; 
str1.PushBack('e'); 
str1.PushBack('f'); 
str1.PushBack('g'); 
str1.PushBack('h'); 
str1.PushBack('i'); 
cout<<str1<<endl; 
cout<<str1.Size()<<endl; 
} 
void text3() 
{ 
String str1("hello"); 
String str2("hello world"); 
String str3(str2); 
str1+=" "; 
str1+="world"; 
cout<<str1<<endl; 
str2.Insert(6," abc "); 
cout<<str2<<endl; 
}

實(shí)現(xiàn)了深拷貝的方法那仫有沒有更加高效的方法呢?當(dāng)然,那就是寫時(shí)拷貝,我們發(fā)現(xiàn)在上述深拷貝的版本里實(shí)現(xiàn)的拷貝構(gòu)造函數(shù)又為新的對象重新開辟空間(防止淺拷貝的后遺癥:淺拷貝是值拷貝使得兩個(gè)指針指向同一塊空間,在析構(gòu)該空間時(shí)對同一塊空間釋放多次就會出現(xiàn)問題),那仫如果我們繼承了淺拷貝的后遺癥-就讓多個(gè)指針指向同一塊空間,此時(shí)我們只需要設(shè)置一個(gè)指針變量讓它記錄指向這塊空間的指針個(gè)數(shù),在析構(gòu)時(shí)只要該指針變量的內(nèi)容為1我們就釋放這塊空間否則就讓計(jì)數(shù)器減1,這就是寫時(shí)拷貝的主要思想,下面就讓我們用寫時(shí)拷貝的方法實(shí)現(xiàn)一個(gè)簡單的String類吧

寫時(shí)拷貝的方法

//寫時(shí)拷貝的方式 
class String 
{ 
friend ostream& operator<<(ostream & os,String &s); 
public: 
String(const char *str="") 
:_str(new char[strlen(str)+1+4]) 
{ 
cout<<"構(gòu)造"<<endl; 
_str+=4; 
*((int *)(_str-4))=1; 
strcpy(_str,str); 
} 
String(String &s) 
{ 
cout<<"拷貝構(gòu)造"<<endl; 
++*((int *)(s._str-4)); 
_str=s._str; 
} 
String &operator=(const String &s) 
{ 
cout<<"賦值語句"<<endl; 
if(--*(int *)(_str-4) == 0) 
{ 
delete[](_str-4); 
} 
++(*(int *)(s._str-4)); 
_str=s._str; 
return *this; 
} 
char &operator[](int index) //寫時(shí)拷貝 
{ 
assert(index >= 0 && index < (int)strlen(_str)); 
if(*(int *)(_str-4) > 1) 
{ 
--*(int *)(_str-4); 
char *tmp=new char[strlen(_str)+5]; 
strcpy(tmp+4,_str); 
delete[](_str-4); 
_str=tmp+4; 
*(int *)(_str-4)=1; 
} 
return _str[index]; 
} 
~String() 
{ 
cout<<"析構(gòu)"<<endl; 
if(--*(int *)(_str-4) == 0) 
{ 
cout<<"釋放"<<endl; 
delete[](_str-4); 
} 
} 
private: 
char *_str; 
}; 
ostream& operator<<(ostream &os,String &s) 
{ 
os<<s._str; 
return os; 
}

在這里我們將指針指向的計(jì)數(shù)器的位置放置在數(shù)據(jù)空間的前四個(gè)字節(jié)處

測試用例:

void test1() 
{ 
String str1("abcd"); 
cout<<str1<<endl; 
String str2(str1); 
cout<<str2<<endl; 
String str3; 
str3=str1; 
cout<<str3<<endl; 
} 
void test2() 
{ 
String str1("abcd"); 
cout<<str1<<endl; 
String str2; 
str2=str1; 
cout<<str2<<endl; 
str2[2]='w'; 
cout<<str2<<endl; 
}

以上所述是小編給大家介紹的C++中sting類的簡單實(shí)現(xiàn)方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評論