溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c++中 有關(guān)自定義string的那些為什么

發(fā)布時(shí)間:2020-04-05 10:10:50 來源:網(wǎng)絡(luò) 閱讀:378 作者:momo462 欄目:編程語言

1、為什么我們要學(xué)會(huì)寫自定義string類

      面試官愛考,你有辦法嗎,沒有-.-c++中 有關(guān)自定義string的那些為什么

2、自定義string類應(yīng)該如何正確書寫

      quote一句c++primer中的話:

       類的安全性和處理正確性的不夠,需要類的設(shè)計(jì)者(也就是我們)去寫拷貝構(gòu)造和賦值運(yùn)算符重載函數(shù),而最困難的不是如何書寫而是讓我們自己本身意識(shí)到需要這樣做。


關(guān)于MyString不得不說的就是:深淺拷貝問題,這個(gè)究其原因就是它的成員變量是個(gè)char *類型的,如果我們懶到要讓編譯器自己幫我們?nèi)ソ?gòu)造、拷貝構(gòu)造,賦值運(yùn)算符重載這些函數(shù),那么問題就是很大滴,因?yàn)樗埠躭azy,它做的操作就是讓兩個(gè)指針指向同一個(gè)地方。

舉個(gè)栗子看:

c++中 有關(guān)自定義string的那些為什么


那么下面就說說如何寫一個(gè)正確的string:

      首先c++中string它是個(gè)類對(duì)吧

      那么我們就寫一個(gè)類出來(成員函數(shù)和成員變量)

class MyString
{
private:
	char *_pData;//對(duì),你沒看錯(cuò),只需要一個(gè)char型指針就可以實(shí)現(xiàn)哦
public:
	//首先一個(gè)類要有構(gòu)造函數(shù)-->保證類的成員變量被正確的初始化
	//第一種寫法----正確但不是最優(yōu)
	MyString(char *pData=NULL)
	{
		if (pData==NULL)
		{
			_pData=new char[1];
			_pData[0]='\0';
		}
		else
		{
			_pData=new char[strlen(pData)+1];
			strcpy(_pData,pData);
		}
	}
	//第二種寫法--比第一種更優(yōu):使用初始化列表
	MyString(char *pData=NULL)
		:pData(new char[strlen(pData)+1])
	{
		strcpy(_pData,pData);
	}
	//既然在構(gòu)造中進(jìn)行了new那么相對(duì)的是不是要在析構(gòu)中去delete?
	~MyString()
	{
		if (_pData)//這里可以直接不用判斷,think about why?
		{
			delete []_pData;
		}
	}
	//拷貝構(gòu)造-----?為什么需要寫,因?yàn)槌蓡T變量是指針,如果我們不進(jìn)行自己去寫
	//就會(huì)出現(xiàn)安全性和正確性的問題,兩個(gè)指針指向一個(gè)空間,當(dāng)其中一個(gè)析構(gòu)后,
	//另外一個(gè)就無法再去訪問這片空間,會(huì)出現(xiàn)非法操作
	//考點(diǎn):形參必須傳入的是該類型的引用,不然在實(shí)參傳給形參時(shí)
	//就會(huì)發(fā)生值傳遞,進(jìn)行拷貝構(gòu)造,那么這個(gè)拷貝構(gòu)造就是一個(gè)死循環(huán)
	//第一種寫法
	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);
	}
	//第三種寫法:只有在構(gòu)造和析構(gòu)的時(shí)候開辟和釋放空間,內(nèi)存空間不易出錯(cuò)
	//不會(huì)出現(xiàn)MyString實(shí)例化對(duì)象的錯(cuò)誤,考慮到了異常安全性
	MyString(const MyString &mstr)
		:_pData(NULL)
		//_pData沒有初始化,隨機(jī)的空間,如果不賦值為空,會(huì)delete失敗
	{
		MyString temp(mstr._pData);
		swap(temp._pData,_pData);
	}
	//賦值運(yùn)算符重載
	//考點(diǎn):1、返回值是該類型引用(考慮到有連等情況a=b=c)
	//考點(diǎn):2、形參是const 引用(不會(huì)改變形參并且效率高)
	//第一種寫法--->缺點(diǎn):如果在new char[]出錯(cuò)的話,很有可能_pData就變成野指針
	//那么MyString返回的對(duì)象就是一個(gè)不正確的對(duì)象,有異常安全性問題
	MyString& operator=(const MyString &mstr)
	{
		//考點(diǎn):3、自己給自己賦值的情況,有沒有考慮到!
		if (this!=&mstr)
		{
			//考點(diǎn):4、先釋放,一定是釋放[]_pData,原因就是構(gòu)造的方式
			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;
	}
	//更優(yōu)寫法
	MyString &operator=(const MyString &mstr)
	{
	    if(&mstr!=this)
	    {
	        MyString temp(mstr._pData);
	        swap(temp._pData,_pData);
	    }
	    return *this;
	}
	//String對(duì)象轉(zhuǎn)換成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;
	}
	//某個(gè)字符
	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;
		}
	}
	
};
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI