首先,先看一下下面的**會出現什麼問題?
class string
else
}~string() }
string(const string& s)
:_data(s._data)
{}private:
char* _data;
};void test()
上面的程式會奔潰,讓我們來分析原因:
這就是所謂的淺拷貝,也稱位拷貝,編譯器只是直接將指標的值拷貝過來,結果多個物件共用同一塊記憶體,當乙個物件將這塊記憶體釋放掉之後,另一些物件不知道該塊空間已經還給了系統,以為還有效,所以在對這段記憶體進行操作的時候,發生了訪問違規。
為了解決這個問題,我們引入深拷貝。
string::string(const string& s)//深拷貝
:_data(new char[strlen(s._data) + 1])
上面**則是str2,重新開闢了一塊空間,並將str1裡的值拷貝到str2這塊空間中。
深拷貝中賦值運算子的過載:
下面有兩種方法,我們來看看哪種方法比較。
方法一:
string& operator=(const string&s)
return *this;
}
方法二:
string& operator=(const string&s)
return *this;
}
一般情況下,兩種方法都可以,但第二種方法更優一些。
方法一中,先將舊的空間釋放掉,然後又重新開闢出與形參同樣大小新的空間,然後將形參的內容拷貝到此空間,此方法有乙個弊端,就是當空間申請失敗時,不僅沒有成功賦值,也破壞了原有被賦值的物件。
方法二中,先開闢出新空間,將這個新空間賦值給tmp這個臨時變數,就算開闢失敗也不會破壞原有的物件。
最後還有一點,就是這裡的返回值是為了支援鏈式訪問。
下面就是面試中string類深拷貝的寫法,一般沒有特殊要求,將必要的成員的成員函式給出就可以了。
class string
else
}~string() }
string(const string& s)
:_data(new char[strlen(s._data)+1])
string& operator=(const string&s)
return *this;
}private:
char* _data;
};
拷貝建構函式的現**法:
string(const string& s)
:_data(null)
賦值運算子過載函式的兩種現**法:
string& operator=(const string&s)
string& operator=(const string&s)
return *this;//為了支援鏈式訪問
}
兩種寫法不同的是,第乙個的拷貝建構函式是在引數列表中完成的,第二種是在函式體內完成的。
以上是關於string類的深淺拷貝問題,當然在面試中也可以寫現**法。
String類與深淺拷貝
1 概念 被複製物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用仍然指向原來的物件。換言之,淺拷貝僅僅複製所考慮的物件,而不是複製它所引用的物件。2 舉例 class string else string const string s string operator const s...
string類的深淺拷貝問題
字串是我們在編寫程式的時候經常用的到的。c 庫已經幫我們實現了乙個功能更加強大的字串類string,我們要去了解它是怎麼實現的。只要是涉及到 string類的地方多少都會涉及到深淺拷貝的問題。在c 中,在用乙個物件初始化另乙個物件時,只複製了成員,並沒有複製資源,使兩個物件同時指向了同一資源的複製方...
面試題一 string類的深淺拷貝
pragma once include using namespace std 淺拷貝 析構物件時會出錯 class cmystring else 拷貝建構函式 cmystring const cmystring str m pdata null 析構函式 cmystring 賦值運算子過載 cmy...