您好,登錄后才能下訂單哦!
這篇“C++深淺拷貝及簡易string類怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C++深淺拷貝及簡易string類怎么實現”文章吧。
對于自定義的string類,如果不顯式定義拷貝構造函數,編譯器會默認生成拷貝構造函數,此時的拷貝方式是淺拷貝,兩個對象會公用一塊兒內存,析構時同一空間被釋放兩次,會導致程序崩潰。
賦值運算符重載也會產生同樣的問題,同時,由于被賦值對象原來有空間,淺拷貝還會導致舊的空間無法找到,造成內存泄漏。
類中設計到資源的管理,拷貝構造函數、賦值運算符重載以及析構函數都要顯示給出,按照深拷貝的方式。
深拷貝的方式讓每個對象都獨立擁有一份資源,不會造成多次釋放導致程序崩潰的問題。
寫時拷貝是通過淺拷貝+引用計數的方式來實現的,引用計數是用來記錄資源的被引用的次數,
可以將這種寫時拷貝的機制想象成“拖延癥”,只有當不得不進行拷貝時,才會開辟新空間進行拷貝
VS中采用的是深拷貝的方式
GCC編譯器采用的是寫時拷貝的方式
簡易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; }
另一種寫法
這種寫法不用定義臨時變量,代碼相對簡潔一點,但是如果new申請空間失敗,舊的空間也無法找到。
析構函數
步驟:
釋放空間
將指針置為空
~string() { if (_str) { delete[]_str; _str = nullptr; } }
構造函數
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); }
賦值運算符重載函數
步驟:
判斷是否為自己給自己賦值
調用拷貝構造函數定義臨時變量
交換臨時變量與當前對象的_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類怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。