【C++學習筆記】----詳解深拷貝,淺拷貝問題

1.什麼是淺拷貝?

概念:淺拷貝也叫位拷貝,編譯器會按照字節將對象的只拷貝過來。
適用場景:一般適用於沒有空間開闢或者釋放的情況下,默認構造函數是淺拷貝。
拷貝指針僅僅拷貝地址,而不會拷貝對應的空間,好處是減少了開闢空間和銷燬空間,但是會造成同一塊空間被多次釋放,從而使得程序崩潰。

2.什麼是深拷貝?

概念:深拷貝是開闢新的空間,將對象所指向的內容拷貝一份。
指針拷貝時,會開闢新的空間,複製一份原來指針的內容,各自有各自的空間儲存,不會造成同一塊空間被多次釋放。

3.樣例

1.這裏展示淺拷貝

namespace xff {
	class string
	{
	public:
		string(const char* str = "")
		{
			_str = new char[strlen(str) + 1];
			strcpy(_str, str);
		}
		~string()	
		{
			std::cout << _str <<std:: endl;
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
		}

	private:
		char* _str;
	};
	// 測試
	void Teststring()
	{
		string s1("hello");
		string s2(s1);
	}
}
int main() {
	xff::Teststring();
	system("pause");
	return 0;
}

2.結果展示

在這裏插入圖片描述

3.出現原因

通過查看內存,我們發現s1和s2的指針指向同一塊空間,那麼在析構的時候,s2先析構直接把_str對應的空間釋放了,當s1再次調用析構函數時,會出現程序崩潰的問題。
在這裏插入圖片描述

4.解決辦法(深拷貝)

1.代碼展示

namespace xff {
	class string
	{
	public:
		string(const char* str = "")
		{
			_str = new char[strlen(str) + 1];
			strcpy(_str, str);
		}
		string(const string& s)
			:_str(nullptr)
		{
			_str = new char[strlen(s._str) + 1];
			strcpy(_str, s._str);
		}

		~string()	
		{
			std::cout << _str <<std:: endl;
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
		}

	private:
		char* _str;
	};
	// 測試
	void Teststring()
	{
		string s1("hello");
		string s2(s1);
	}
}
int main() {
	xff::Teststring();
	system("pause");
	return 0;
}

2.結果展示
在這裏插入圖片描述
3.內存查看
在這裏插入圖片描述

4.總結

我們通過查看內存發現s1和s2的內容雖然相同,但是地址卻不同,在析構的時候互相不干擾,就不會出現同一塊空間多次釋放的問題。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章