亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

c++中 有關自定義string的那些為什么

發布時間:2020-04-05 10:10:50 來源:網絡 閱讀:376 作者:momo462 欄目:編程語言

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

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

2、自定義string類應該如何正確書寫

      quote一句c++primer中的話:

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


關于MyString不得不說的就是:深淺拷貝問題,這個究其原因就是它的成員變量是個char *類型的,如果我們懶到要讓編譯器自己幫我們去建構造、拷貝構造,賦值運算符重載這些函數,那么問題就是很大滴,因為它也很lazy,它做的操作就是讓兩個指針指向同一個地方。

舉個栗子看:

c++中 有關自定義string的那些為什么


那么下面就說說如何寫一個正確的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;
		}
	}
	
};
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

靖西县| 临潭县| 利辛县| 汽车| 樟树市| 岱山县| 图木舒克市| 仁布县| 马龙县| 文昌市| 丹江口市| 新乡市| 灌南县| 炉霍县| 安图县| 永州市| 山阴县| 周至县| 定边县| 漳浦县| 大渡口区| 彝良县| 都安| 双柏县| 遂溪县| 聂荣县| 大悟县| 秦皇岛市| 千阳县| 麻栗坡县| 漯河市| 磐石市| 遵义市| 大渡口区| 壤塘县| 文成县| 岐山县| 襄城县| 凉山| 同江市| 濮阳市|