首先定義string類,而並不實現其成員函式。
class string
;位拷貝拷貝的是位址,而值拷貝則拷貝的是內容。如果定義兩個string物件a和b。a.m_data和b.m_data分別指向一段區域,
a.m_data="windows",
b.m_data=「linux";
如果未重寫賦值函式,將b賦給a;則編譯器會預設進行位拷貝,
a.m_data=
b.m_data
則a.m_data和b.m_data指向同一塊區域,雖然
a.m_data指向的內容會改變成"linux",但是
這樣容易出現這些問題:
(1):
a.m_data
原來指向的記憶體區域未釋放,造成記憶體洩露。
(2):
a.m_data
和b.m_data
指向同一塊區域,任何一方改變都會影響另一方
(3):當物件被析構時,
b.m_data
被釋放兩次。
對於編譯器,如果不主動編寫拷貝函式和賦值函式,它會以「位拷貝」的方式自動生成預設的函式。
如果重寫賦值函式和拷貝建構函式後,
a.m_data=
b.m_data,
進行的是值拷貝,
會將b.m_data的內容賦給
a.m_data,
a.m_data還是指向原來的記憶體區域,但是其內容改變。
拷貝建構函式和賦值函式非常容易混淆,常導致錯寫、錯用。拷貝建構函式是在對
象被建立時呼叫的,而賦值函式只能被已經存在了的物件呼叫。以下程式中,第三
個語句和第四個語句很相似,你分得清楚哪個呼叫了拷貝建構函式,哪個呼叫了賦
值函式嗎?
string a(「hello」);
string b(「world」);
string c = a; // 呼叫了拷貝建構函式,最好寫成 c(a);
c = b; // 呼叫了賦值函式
本例中第三個語句的風格較差,宜改寫成string c(a) 以區別於第四個語句。
位拷貝 值拷貝 淺拷貝 深拷貝
位拷貝拷貝 的是位址 也叫淺拷貝 而 值拷貝則拷貝的是內容 也叫深拷貝 如果不主動編寫拷貝建構函式和賦值函式,編譯器將以 位拷貝 的方式自動生成預設的函式 現將 a賦給 b,預設賦值函式的 位拷貝 意味著執行 b.m data a.m data。這將造成三個錯誤 一是 b.m data 原有的記憶體...
淺拷貝 深拷貝
copy mutablecopy copy 不管是可變的,還是不可變的,結果都是不可變的 mutablecopy 不管是不可變的,還是可變的,結果都是可變的 nsmutablestring str nsmutablestring stringwithformat a nsarray arr1 str...
深拷貝 淺拷貝
c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...