亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

1. 經(jīng)典的string類問題

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

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

// 為了和標(biāo)準(zhǔn)庫區(qū)分,此處使用String
class String
{
public:
	//String()
	//	:_str(new char[1])
	//{
	//	*_str = '\0';
	//}
	
	//String(const char* str = "\0")	// 錯誤示范
	//String(const char* str = nullptr)	// 錯誤示范
	String(const char* str = "")
	{
		// 構(gòu)造String類對象時,如果傳遞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;
};

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

在這里插入圖片描述

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

2. 淺拷貝

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

就像一個家庭中有兩個孩子,但父母只買了一份玩具,兩個孩子愿意一塊玩,則萬事大吉,萬一不想分享就你爭我奪,玩具損壞。


在這里插入圖片描述

可以采用深拷貝解決淺拷貝問題,即:每個對象都有一份獨立的資源,不要和其他對象共享。父母給每個孩子都買一份玩具,各自玩各自的就不會有問題了。


在這里插入圖片描述

3. 深拷貝

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

3.1 傳統(tǒng)寫法的String類

class String
{
public:
	String(const char* str = "")
	{
		// 構(gòu)造String類對象時,如果傳遞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)代寫法的String類

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);
	}
	
	// 對比下和上面的賦值那個實現(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)寫法就是老老實實自己開空間、自己拷貝數(shù)據(jù)、自己刪除舊空間;而現(xiàn)代寫法則利用了swap()函數(shù)以及局部變量出作用域自動銷毀的特性,讓函數(shù)和編譯器幫我們“打工”,我們只要坐享其成即可。這兩種方式在效率上并沒有什么區(qū)別,只是讓代碼看起來更簡潔,但這又會使代碼的可讀性降低??傮w來說,我還是更偏向于傳統(tǒng)寫法。

4. 寫時拷貝

在這里插入圖片描述

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

引用計數(shù):用來記錄資源使用者的個數(shù)。在構(gòu)造時,將資源的計數(shù)給成1,每增加一個對象使用該資源,就給計數(shù)增加1,當(dāng)某個對象被銷毀時,先給該計數(shù)-1,然后再檢查是否需要釋放資源,如果計數(shù)為1,說明該對象是資源的最后一個使用者,將該資源釋放;否則就不能釋放,因為還有其他對象也在使用該資源。

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

相關(guān)文章

  • C++哈希應(yīng)用之位圖,哈希切分與布隆過濾器詳解

    C++哈希應(yīng)用之位圖,哈希切分與布隆過濾器詳解

    這篇文章主要為大家詳細(xì)介紹了C++哈希應(yīng)用中的位圖、哈希切分與布隆過濾器,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,需要的可以參考一下
    2023-04-04
  • C語言關(guān)于自定義數(shù)據(jù)類型之枚舉和聯(lián)合體詳解

    C語言關(guān)于自定義數(shù)據(jù)類型之枚舉和聯(lián)合體詳解

    枚舉顧名思義就是把所有的可能性列舉出來,像一個星期分為七天我們就可以使用枚舉,聯(lián)合體是由關(guān)鍵字union和標(biāo)簽定義的,和枚舉是一樣的定義方式,不一樣的是,一個聯(lián)合體只有一塊內(nèi)存空間,什么意思呢,就相當(dāng)于只開辟最大的變量的內(nèi)存,其他的變量都在那個變量占據(jù)空間
    2021-11-11
  • 詳解C++ 共享數(shù)據(jù)保護機制

    詳解C++ 共享數(shù)據(jù)保護機制

    這篇文章主要介紹了詳解C++ 共享數(shù)據(jù)保護機制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下
    2021-02-02
  • 在C語言里單引號和雙引號的區(qū)別

    在C語言里單引號和雙引號的區(qū)別

    這篇文章主要介紹了在C語言里單引號和雙引號的區(qū)別,本文通過代碼的實例和注釋的詳細(xì)的說明了單引號和雙引號的概念與區(qū)別,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實現(xiàn)LeetCode(16.最近三數(shù)之和)

    C++實現(xiàn)LeetCode(16.最近三數(shù)之和)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(16.最近三數(shù)之和),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 一篇文章徹底搞懂C++常見容器

    一篇文章徹底搞懂C++常見容器

    容器就是一些特定類型對象的集合,容器可以分為順序容器和關(guān)聯(lián)容器,下面這篇文章主要給大家介紹了關(guān)于C++常見容器的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • 你知道C語言中#和##表示的意義嗎

    你知道C語言中#和##表示的意義嗎

    如標(biāo)題,這篇文章會講解C語言中的#和##是啥意思。我相信,大部分朋友應(yīng)該都沒怎么用過,這兩個玩意的使用條件也相當(dāng)苛刻,快跟隨小編一起來看看吧
    2023-04-04
  • C語言嵌入informix基礎(chǔ)入門示例講解

    C語言嵌入informix基礎(chǔ)入門示例講解

    這篇文章主要介紹了C語言嵌入informix基礎(chǔ)方法,大家參考使用
    2013-11-11
  • C語言算法練習(xí)之?dāng)?shù)組元素排序

    C語言算法練習(xí)之?dāng)?shù)組元素排序

    這篇文章主要為大家介紹了C語言算法練習(xí)中數(shù)組元素排序的實現(xiàn)方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-09-09
  • C++ 重載與重寫的區(qū)別與實現(xiàn)

    C++ 重載與重寫的區(qū)別與實現(xiàn)

    在面向?qū)ο笳Z言中,經(jīng)常提到重載與重寫,本文主要介紹了C++ 重載與重寫的區(qū)別與實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-01-01

最新評論