C++中sting類的簡單實(shí)現(xià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í)變量出作用域就會自動(dòng)調(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)站的支持!
上一篇:C語言 以數(shù)據(jù)塊的形式讀寫文件詳解及實(shí)現(xiàn)代碼
欄 目:C語言
本文標(biāo)題:C++中sting類的簡單實(shí)現(xiàn)方法
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2092.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對數(shù)怎么表達(dá)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 01-10APUE筆記之:進(jìn)程環(huán)境詳解
- 01-10c++中inline的用法分析
- 01-10如何尋找數(shù)組中的第二大數(shù)


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢dedecms什么時(shí)候用欄目交叉功能?