最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

掌握C++:揭秘寫(xiě)時(shí)拷貝與淺深拷貝之間的關(guān)系

 更新時(shí)間:2024年01月30日 09:01:17   作者:字節(jié)連結(jié)  
探索C++的奧秘,本指南將揭秘寫(xiě)時(shí)拷貝與淺深拷貝之間的微妙關(guān)系,摸索這些復(fù)雜概念背后的邏輯,讓你的編程技能瞬間提升,來(lái)吧,讓我們一起進(jìn)入這個(gè)引人入勝的C++世界!

1. 經(jīng)典的string類(lèi)問(wèn)題

上一篇博客已經(jīng)對(duì)string類(lèi)進(jìn)行了簡(jiǎn)單的介紹,大家只要能夠正常使用即可。

在面試中,面試官總喜歡讓學(xué)生自己來(lái)模擬實(shí)現(xiàn)string類(lèi),最主要是實(shí)現(xiàn)string類(lèi)的構(gòu)造、拷貝構(gòu)造、賦值運(yùn)算符重載以及析構(gòu)函數(shù)。大家看下以下string類(lèi)的實(shí)現(xiàn)是否有問(wèn)題?

// 為了和標(biāo)準(zhǔn)庫(kù)區(qū)分,此處使用String
class String
{
public:
	//String()
	//	:_str(new char[1])
	//{
	//	*_str = '\0';
	//}
	
	//String(const char* str = "\0")	// 錯(cuò)誤示范
	//String(const char* str = nullptr)	// 錯(cuò)誤示范
	String(const char* str = "")
	{
		// 構(gòu)造String類(lèi)對(duì)象時(shí),如果傳遞nullptr指針,可以認(rèn)為程序非法
		if (nullptr == str)
		{
			assert(false);
			return;
		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	
private:
	char* _str;
};

// 測(cè)試
void TestString()
{
	String s1("hello string");
	String s2(s1);
}

在這里插入圖片描述

說(shuō)明:上述String類(lèi)沒(méi)有顯式定義其拷貝構(gòu)造函數(shù)與賦值運(yùn)算符重載,此時(shí)編譯器會(huì)合成默認(rèn)的,當(dāng)用s1構(gòu)造s2時(shí),編譯器會(huì)調(diào)用默認(rèn)的拷貝構(gòu)造。最終導(dǎo)致的問(wèn)題時(shí),s1、s2共用同一塊內(nèi)存空間,在釋放時(shí)同一塊空間被釋放多次而引起程序崩潰,這種拷貝方式,稱(chēng)為淺拷貝。

2. 淺拷貝

淺拷貝:也稱(chēng)位拷貝,編譯器只是將對(duì)象中的值拷貝過(guò)來(lái)。如果對(duì)象中管理資源,最后就會(huì)導(dǎo)致多個(gè)對(duì)象共享同一份資源,當(dāng)一個(gè)對(duì)象銷(xiāo)毀時(shí)就會(huì)將該資源釋放掉,而此時(shí)另一些對(duì)象不知道該資源已經(jīng)被釋放,以為還有效,所以當(dāng)繼續(xù)對(duì)資源進(jìn)行操作時(shí),就會(huì)發(fā)生訪問(wèn)違規(guī)。

就像一個(gè)家庭中有兩個(gè)孩子,但父母只買(mǎi)了一份玩具,兩個(gè)孩子愿意一塊玩,則萬(wàn)事大吉,萬(wàn)一不想分享就你爭(zhēng)我?jiàn)Z,玩具損壞。


在這里插入圖片描述

可以采用深拷貝解決淺拷貝問(wèn)題,即:每個(gè)對(duì)象都有一份獨(dú)立的資源,不要和其他對(duì)象共享。父母給每個(gè)孩子都買(mǎi)一份玩具,各自玩各自的就不會(huì)有問(wèn)題了。


在這里插入圖片描述

3. 深拷貝

如果一個(gè)類(lèi)中涉及到資源的管理,其拷貝構(gòu)造函數(shù),賦值運(yùn)算符重載以及析構(gòu)函數(shù)必須要顯式給出。一般情況都是按照深拷貝方式提供。
在這里插入圖片描述

3.1 傳統(tǒng)寫(xiě)法的String類(lèi)

class String
{
public:
	String(const char* str = "")
	{
		// 構(gòu)造String類(lèi)對(duì)象時(shí),如果傳遞nullptr指針,可以認(rèn)為程序非法
		if (nullptr == str)
		{
			assert(false);
			return;
		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	
	String(const String& s)
		: _str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}
	
	String& operator=(const String& s)
	{
		if (this != &s)
		{
			char* pStr = new char[strlen(s._str) + 1];
			strcpy(pStr, s._str);
			delete[] _str;
			_str = pStr;
		}
		return *this;
	}
	
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	
private:
	char* _str;
};

3.2 現(xiàn)代寫(xiě)法的String類(lèi)

class String
{
public:
	String(const char* str = "")
	{
		if (nullptr == str)
		{
			assert(false);
			return;
		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	
	String(const String& s)
		: _str(nullptr)
	{
		String strTmp(s._str);
		swap(_str, strTmp._str);
	}
	
	// 對(duì)比下和上面的賦值那個(gè)實(shí)現(xiàn)比較好?
	String& operator=(String s)
	{
		swap(_str, s._str);
		return *this;
	}
	
	//String& operator=(const String& s)
	//{
	//	if (this != &s)
	//	{
	//		String strTmp(s);
	//		swap(_str, strTmp._str);
	//	}
	//	return *this;
	//}

	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	
private:
	char* _str;
};

傳統(tǒng)寫(xiě)法就是老老實(shí)實(shí)自己開(kāi)空間、自己拷貝數(shù)據(jù)、自己刪除舊空間;而現(xiàn)代寫(xiě)法則利用了swap()函數(shù)以及局部變量出作用域自動(dòng)銷(xiāo)毀的特性,讓函數(shù)和編譯器幫我們“打工”,我們只要坐享其成即可。這兩種方式在效率上并沒(méi)有什么區(qū)別,只是讓代碼看起來(lái)更簡(jiǎn)潔,但這又會(huì)使代碼的可讀性降低??傮w來(lái)說(shuō),我還是更偏向于傳統(tǒng)寫(xiě)法。

4. 寫(xiě)時(shí)拷貝

在這里插入圖片描述

寫(xiě)時(shí)拷貝就是一種拖延癥,是在淺拷貝的基礎(chǔ)之上增加了引用計(jì)數(shù)的方式來(lái)實(shí)現(xiàn)的。

引用計(jì)數(shù):用來(lái)記錄資源使用者的個(gè)數(shù)。在構(gòu)造時(shí),將資源的計(jì)數(shù)給成1,每增加一個(gè)對(duì)象使用該資源,就給計(jì)數(shù)增加1,當(dāng)某個(gè)對(duì)象被銷(xiāo)毀時(shí),先給該計(jì)數(shù)-1,然后再檢查是否需要釋放資源,如果計(jì)數(shù)為1,說(shuō)明該對(duì)象是資源的最后一個(gè)使用者,將該資源釋放;否則就不能釋放,因?yàn)檫€有其他對(duì)象也在使用該資源。

到此這篇關(guān)于掌握C++:揭秘寫(xiě)時(shí)拷貝與淺深拷貝之間的關(guān)系的文章就介紹到這了,更多相關(guān)C++ 淺拷貝 深拷貝 寫(xiě)時(shí)拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++ vector模擬實(shí)現(xiàn)的全過(guò)程

    c++ vector模擬實(shí)現(xiàn)的全過(guò)程

    這篇文章主要給大家介紹了關(guān)于c++ vector的模擬實(shí)現(xiàn)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 淺談C語(yǔ)言中include

    淺談C語(yǔ)言中include""與include<>的區(qū)別

    C語(yǔ)言中包含文件有兩種包含符號(hào),一個(gè)是<>尖括號(hào),另一個(gè)是""雙引號(hào)。那么這兩個(gè)有什么區(qū)別呢?本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-06-06
  • C++的最短路徑的弗洛伊德算法案例講解

    C++的最短路徑的弗洛伊德算法案例講解

    這篇文章主要介紹了C++的最短路徑的弗洛伊德算法案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++中友元函數(shù)(friend)解析

    C++中友元函數(shù)(friend)解析

    這篇文章主要分享了C++友元函數(shù)講解,C++提供了一種形式的訪問(wèn)權(quán)限,叫做友元,友元有三種,分別是友元函數(shù)、友元類(lèi)和友元成員函數(shù),下面將詳細(xì)介紹該內(nèi)容,需要的小伙伴可以參考一下
    2022-01-01
  • C++實(shí)現(xiàn)順序表的常用操作(插入刪出查找輸出)

    C++實(shí)現(xiàn)順序表的常用操作(插入刪出查找輸出)

    實(shí)現(xiàn)順序表的插入,刪除,查找,輸出操作在C語(yǔ)言中經(jīng)常用到。下面小編給大家整理實(shí)現(xiàn)代碼,一起看下吧
    2016-08-08
  • 淺談C語(yǔ)言宏替換與宏定義高級(jí)用法

    淺談C語(yǔ)言宏替換與宏定義高級(jí)用法

    本文詳細(xì)介紹了C語(yǔ)言中的宏替換與宏定義高級(jí)用法,包括預(yù)處理核心原理、宏定義的無(wú)參數(shù)和帶參數(shù)宏、宏的陷阱與優(yōu)化、內(nèi)置宏、條件編譯以及預(yù)處理實(shí)例,感興趣的可以了解一下
    2025-12-12
  • Dev-C++調(diào)試方法的具體使用

    Dev-C++調(diào)試方法的具體使用

    本文主要介紹了Dev-C++調(diào)試方法的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C語(yǔ)言之實(shí)現(xiàn)單鏈表指定結(jié)點(diǎn)的插入方式

    C語(yǔ)言之實(shí)現(xiàn)單鏈表指定結(jié)點(diǎn)的插入方式

    這篇文章主要介紹了C語(yǔ)言之實(shí)現(xiàn)單鏈表指定結(jié)點(diǎn)的插入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++調(diào)試記錄與心得分享

    C++調(diào)試記錄與心得分享

    本文給大家詳細(xì)記錄了一次C++的調(diào)試過(guò)程,以及調(diào)試的心得,非常的實(shí)用,有需要的小伙伴可以參考下
    2017-07-07
  • Qt+Quick實(shí)現(xiàn)圖片演示器的開(kāi)發(fā)

    Qt+Quick實(shí)現(xiàn)圖片演示器的開(kāi)發(fā)

    這篇文章主要為大家詳細(xì)介紹了Qt如何利用Quick實(shí)現(xiàn)圖片演示器的開(kāi)發(fā),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,需要的可以參考一下
    2023-01-01

最新評(píng)論

麦盖提县| 六盘水市| 墨竹工卡县| 葫芦岛市| 揭阳市| 安岳县| 海南省| 深水埗区| 郑州市| 嘉义县| 平湖市| 尖扎县| 金湖县| 边坝县| 延长县| 锦州市| 仁布县| 桑植县| 崇信县| 文昌市| 扶风县| 赤峰市| 永康市| 五寨县| 石首市| 鹿邑县| 麦盖提县| 遂昌县| 莲花县| 崇信县| 尉氏县| 蓝山县| 高青县| 嵊泗县| 蓬莱市| 六盘水市| 甘孜| 石嘴山市| 迭部县| 潮安县| 保康县|