1、為什么我們要學會寫自定義string類

面試官愛考,你有辦法嗎,沒有-.-
2、自定義string類應該如何正確書寫
quote一句c++primer中的話:
類的安全性和處理正確性的不夠,需要類的設計者(也就是我們)去寫拷貝構造和賦值運算符重載函數,而最困難的不是如何書寫而是讓我們自己本身意識到需要這樣做。
關于MyString不得不說的就是:深淺拷貝問題,這個究其原因就是它的成員變量是個char *類型的,如果我們懶到要讓編譯器自己幫我們去建構造、拷貝構造,賦值運算符重載這些函數,那么問題就是很大滴,因為它也很lazy,它做的操作就是讓兩個指針指向同一個地方。
舉個栗子看:

那么下面就說說如何寫一個正確的string:
首先c++中string它是個類對吧
那么我們就寫一個類出來(成員函數和成員變量)
class MyString
{
private:
char *_pData;//對,你沒看錯,只需要一個char型指針就可以實現哦
public:
//首先一個類要有構造函數-->保證類的成員變量被正確的初始化
//第一種寫法----正確但不是最優
MyString(char *pData=NULL)
{
if (pData==NULL)
{
_pData=new char[1];
_pData[0]='\0';
}
else
{
_pData=new char[strlen(pData)+1];
strcpy(_pData,pData);
}
}
//第二種寫法--比第一種更優:使用初始化列表
MyString(char *pData=NULL)
:pData(new char[strlen(pData)+1])
{
strcpy(_pData,pData);
}
//既然在構造中進行了new那么相對的是不是要在析構中去delete?
~MyString()
{
if (_pData)//這里可以直接不用判斷,think about why?
{
delete []_pData;
}
}
//拷貝構造-----?為什么需要寫,因為成員變量是指針,如果我們不進行自己去寫
//就會出現安全性和正確性的問題,兩個指針指向一個空間,當其中一個析構后,
//另外一個就無法再去訪問這片空間,會出現非法操作
//考點:形參必須傳入的是該類型的引用,不然在實參傳給形參時
//就會發生值傳遞,進行拷貝構造,那么這個拷貝構造就是一個死循環
//第一種寫法
MyString(const MyString &mstr)
{
if (strlen(mstr._pData)==0)
{
_pData=new char[1];
_pData[0]='\0';
}
else
{
_pData=new char[strlen(mstr._pData)+1];
strcpy(_pData,mstr._pData);
}
}
//第二種寫法
MyString(const MyString &mstr)
:_pData(new char[strlen(mstr._pData)+1])
{
strcpy(_pData,mstr._pData);
}
//第三種寫法:只有在構造和析構的時候開辟和釋放空間,內存空間不易出錯
//不會出現MyString實例化對象的錯誤,考慮到了異常安全性
MyString(const MyString &mstr)
:_pData(NULL)
//_pData沒有初始化,隨機的空間,如果不賦值為空,會delete失敗
{
MyString temp(mstr._pData);
swap(temp._pData,_pData);
}
//賦值運算符重載
//考點:1、返回值是該類型引用(考慮到有連等情況a=b=c)
//考點:2、形參是const 引用(不會改變形參并且效率高)
//第一種寫法--->缺點:如果在new char[]出錯的話,很有可能_pData就變成野指針
//那么MyString返回的對象就是一個不正確的對象,有異常安全性問題
MyString& operator=(const MyString &mstr)
{
//考點:3、自己給自己賦值的情況,有沒有考慮到!
if (this!=&mstr)
{
//考點:4、先釋放,一定是釋放[]_pData,原因就是構造的方式
delete []_pData;
//再開辟
_pData=new char[strlen(mstr._pData)+1];
strcpy(_pData,mstr._pData);
}
return *this;
}
//第二種寫法
MyString &operator=(const MyString &mstr)
{
//先開辟
char *temp=new char[strlen(mstr._pData)+1];
if (temp==NULL)
{
return *this;
}
//在釋放
delete []_pData;
_pData=temp;
strcpy(_pData,mstr._pData);
return *this;
}
//第三種寫法
MyString &operator=(MyString mstr)
{
swap(mstr._pData,_pData);
return *this;
}
//更優寫法
MyString &operator=(const MyString &mstr)
{
if(&mstr!=this)
{
MyString temp(mstr._pData);
swap(temp._pData,_pData);
}
return *this;
}
//String對象轉換成const char*
const char* C_str()const
{
return _pData;
}
//求字符串長度
size_t Size()
{
return strlen(_pData);
}
//判斷是否相等
bool operator==(const MyString &mstr)const
{
if (&mstr!=this)
{
if(!strcmp(_pData,mstr._pData))
{
return false;
}
}
return true;
}
//某個字符
char operator[](size_t pos)const
{
if (pos<strlen(_pData)&&pos>=0)
{
return _pData[pos];
}
else
{
return 0;
}
}
//字符串比較
int operator<(const MyString &mstr)const
{
int truth=strcmp(_pData,mstr._pData);
if (truth>0)
{
return -1;
}
else if (truth==0)
{
return 0;
}
else
{
return 1;
}
}
};創新互聯www.cdcxhl.cn,專業提供香港、美國云服務器,動態BGP最優骨干路由自動選擇,持續穩定高效的網絡助力業務部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統配攻擊溯源,準確進行流量調度,確保服務器高可用性。佳節活動現已開啟,新人活動云服務器買多久送多久。
網頁題目:c++中有關自定義string的那些為什么-創新互聯
分享鏈接:http://www.js-pz168.com/article42/dgojec.html
成都網站建設公司_創新互聯,為您提供虛擬主機、營銷型網站建設、全網營銷推廣、小程序開發、品牌網站建設、手機網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯