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

溫馨提示×

溫馨提示×

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

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

C++深淺拷貝及簡易string類怎么實現

發布時間:2023-02-07 09:28:38 來源:億速云 閱讀:107 作者:iii 欄目:開發技術

這篇“C++深淺拷貝及簡易string類怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C++深淺拷貝及簡易string類怎么實現”文章吧。

    三種拷貝方式

    淺拷貝

    對于自定義的string類,如果不顯式定義拷貝構造函數,編譯器會默認生成拷貝構造函數,此時的拷貝方式是淺拷貝,兩個對象會公用一塊兒內存,析構時同一空間被釋放兩次,會導致程序崩潰。

    C++深淺拷貝及簡易string類怎么實現

    賦值運算符重載也會產生同樣的問題,同時,由于被賦值對象原來有空間,淺拷貝還會導致舊的空間無法找到,造成內存泄漏。

    深拷貝

    類中設計到資源的管理,拷貝構造函數、賦值運算符重載以及析構函數都要顯示給出,按照深拷貝的方式。

    深拷貝的方式讓每個對象都獨立擁有一份資源,不會造成多次釋放導致程序崩潰的問題。

    C++深淺拷貝及簡易string類怎么實現

    寫時拷貝

    寫時拷貝是通過淺拷貝+引用計數的方式來實現的,引用計數是用來記錄資源的被引用的次數,

    C++深淺拷貝及簡易string類怎么實現

    C++深淺拷貝及簡易string類怎么實現

    可以將這種寫時拷貝的機制想象成“拖延癥”,只有當不得不進行拷貝時,才會開辟新空間進行拷貝

    VS與GCC中的拷貝方式

    Windows VS2022

    VS中采用的是深拷貝的方式

    C++深淺拷貝及簡易string類怎么實現

    Linux GCC

    GCC編譯器采用的是寫時拷貝的方式

    C++深淺拷貝及簡易string類怎么實現

    簡易string類

    簡易string類主要實現四個功能,即構造函數、拷貝構造函數、析構函數、賦值運算符重載,主要考察深淺拷貝

    實現簡易string類有兩種代碼風格,一種傳統版寫法,代碼復用性第,可讀性較好;另一種稱為現代版寫法,代碼復用性高,但是較難理解。

    傳統版寫法的string類

    構造函數

    步驟:

    • 判斷是否為空指針,string類不允許nullptr構造對象

    • 申請新空間

    • 將字符串中的值拷貝到申請的空間

    string(const char* str = "")
    {
    	if (nullptr == str)
    	{
    		assert(false);
    		return;
    	}
    	//+1是因為有'\0',strcpy會將源字符串中的'\0'拷貝到目標空間
    	_str = new char[strlen(str) + 1];
    	strcpy(_str, str);
    }

    拷貝構造函數

    步驟:

    • 開辟空間

    • 用源對象的_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* temp = new char[strlen(s._str) + 1];
    		strcpy(temp, s._str);
    		delete[] _str;
    		_str = temp;
    	}
    	return *this;
    }

    另一種寫法

    C++深淺拷貝及簡易string類怎么實現

    這種寫法不用定義臨時變量,代碼相對簡潔一點,但是如果new申請空間失敗,舊的空間也無法找到。

    析構函數

    步驟:

    • 釋放空間

    • 將指針置為空

    ~string()
    {
        if (_str)
        {
            delete[]_str;
            _str = nullptr;
        }
    }

    現代版寫法string類

    構造函數

    string(const char* str = "")
    {
    	if (str == nullptr)
    	{
    		assert(false);
    	}
    	_str = new char[strlen(str) + 1];
    	strcpy(_str, str);
    }

    拷貝構造函數

    拷貝構造函數中利用構造函數,實現了代碼的復用

    步驟:

    • 在初始化列表中將_str置為空

    • 定義一個臨時的string類對象,指向要拷貝的對象相同位置

    • 交換臨時對象與當前對象的_str

    string(const string& s)
    	:_str(nullptr)
    {
    	//調用構造函數
    	string temp(s._str);
    	//交換以后temp指向空,函數退出后被銷毀
    	swap(_str, temp._str);
    }

    C++深淺拷貝及簡易string類怎么實現

    賦值運算符重載函數

    步驟:

    • 判斷是否為自己給自己賦值

    • 調用拷貝構造函數定義臨時變量

    • 交換臨時變量與當前對象的_str

    string& operator=(string& s)
    {
    	if (this != &s)
    	{
    		string temp(s);
    		swap(_str, s._str);
    	}
    	return *this;
    }

    更簡潔的寫法:

    string& operator=(string s)
    {
    	//傳參調用拷貝構造函數,不用判斷是否給自己賦值
    	swap(_str, s._str);
    	return *this;
    }

    析構函數

    ~string()
    {
    	if (_str)
    	{
    		delete[] _str;
    		_str = nullptr;
    	}
    }

    以上就是關于“C++深淺拷貝及簡易string類怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

    向AI問一下細節

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

    AI

    乌拉特后旗| 满城县| 东光县| 砚山县| 奉化市| 凭祥市| 黔西县| 清涧县| 仁寿县| 永善县| 娄底市| 望江县| 普陀区| 乌鲁木齐市| 淮北市| 海兴县| 白银市| 大埔县| 西乌珠穆沁旗| 延庆县| 濉溪县| 武隆县| 吉木乃县| 镇巴县| 许昌市| 高阳县| 长汀县| 澎湖县| 四子王旗| 大足县| 临湘市| 江川县| 彭州市| 怀集县| 弋阳县| 津市市| 南汇区| 抚远县| 台中市| 成都市| 磐安县|