本文主要介紹了拷貝建構函式和賦值運算子的區別,以及在什麼時候呼叫拷貝建構函式、什麼情況下呼叫賦值運算子。最後,簡單的分析了下深拷貝和淺拷貝的問題。
拷貝建構函式和賦值運算子
在預設情況下(使用者沒有定義,但是也沒有顯式的刪除),編譯器會自動的隱式生成乙個拷貝建構函式和賦值運算子。但使用者可以使用delete來指定不生成拷貝建構函式和賦值運算子,這樣的物件就不能通過值傳遞,也不能進行賦值運算。
class person
;上面的定義的類person顯式的刪除了拷貝建構函式和賦值運算子,在需要呼叫拷貝建構函式或者賦值運算子的地方,會提示_無法呼叫該函式,它是已刪除的函式_。
還有一點需要注意的是,拷貝建構函式必須以引用的方式傳遞引數。這是因為,在值傳遞的方式傳遞給乙個函式的時候,會呼叫拷貝建構函式生成函式的實參。如果拷貝建構函式的引數仍然是以值的方式,就會無限迴圈的呼叫下去,直到函式的棧溢位。
何時呼叫
拷貝建構函式和賦值運算子的行為比較相似,都是將乙個物件的值複製給另乙個物件;但是其結果卻有些不同,拷貝建構函式使用傳入物件的值生成乙個新的物件的例項,而賦值運算子是將物件的值複製給乙個已經存在的例項。這種區別從兩者的名字也可以很輕易的分辨出來,拷貝建構函式也是一種建構函式,那麼它的功能就是建立乙個新的物件例項;賦值運算子是執行某種運算,將乙個物件的值複製給另乙個物件(已經存在的)。呼叫的是拷貝建構函式還是賦值運算子,主要是看是否有新的物件例項產生。如果產生了新的物件例項,那呼叫的就是拷貝建構函式;如果沒有,那就是對已有的物件賦值,呼叫的是賦值運算子。kaajh
呼叫拷貝建構函式主要有以下場景:
**如下:
class person
person程式設計客棧(const person& p)
person& operator=(const person& p)
private:
i程式設計客棧nt age;
string name;
};void f(person p)
person f1()
int main()
上面**中定義了乙個類person,顯式的定義了拷貝建構函式和賦值運算子。然後定義了兩個函式:f,以值的方式參傳入person物件;f1,以值的方式返回person物件。在main中模擬了5中場景,測試呼叫的是拷貝建構函式還是賦值運算子。執行結果如下:
分析如下:
深拷貝、淺拷貝
說到拷貝建構函式,就不得不提深拷貝和淺拷貝。通常,預設生成的拷貝建構函式和賦值運算子,只是簡單的進行值的複製。例如:上面的person類,字段只有int和string兩種型別,這在拷貝或者賦值時進行值複製建立的出來的物件和源物件也是沒有任何關聯,對源物件的任何操作都不會影響到拷貝出來的物件。反之,假如person有乙個物件為int *,這時在拷貝時還只是進行值複製,那麼建立出來的person物件的int *的值就和源物件的int *指向的是同乙個位置。任何乙個物件對該值的修改都會影響到另乙個物件,這種情況就是淺拷貝。
深拷貝和淺拷貝主要是針對類中的指標和動態分配的空間來說的,因為對於指標只是簡單的值複製並不能分割開兩個物件的關聯,任何乙個物件對該指標的操作都會程式設計客棧影響到另乙個物件。這時候就需要提供自定義的深拷貝的拷貝建構函式,消除這種影響。通常的原則是:
對於拷貝建構函式的實現要確保以下幾點:
總結本文標題: 詳解c++ 拷貝建構函式和賦值運算子
本文位址:
C 拷貝建構函式和 賦值運算子詳解
首先明確一點 系統已經提供了預設的 拷貝建構函式 和 複製運算子。即所謂的淺拷貝。但有時,我們必須提供自己重寫。一般是在有指標的情況下重寫。舉個簡單的例子,沒有指標,其實不必重寫,只是為了演示 cpp class fraction fraction fraction const fraction f...
C 拷貝建構函式和 賦值運算子詳解
首先明確一點 系統已經提供了預設的 拷貝建構函式 和 複製運算子。即所謂的淺拷貝。但有時,我們必須提供自己重寫。一般是在有指標的情況下重寫。舉個簡單的例子,沒有指標,其實不必重寫,只是為了演示 class fraction fraction fraction const fraction fr fr...
C 拷貝建構函式和賦值運算子
本文主要介紹了拷貝建構函式和賦值運算子的區別,以及在什麼時候呼叫拷貝建構函式 什麼情況下呼叫賦值運算子。最後,簡單的分析了下深拷貝和淺拷貝的問題。在預設情況下 使用者沒有定義,但是也沒有顯式的刪除 編譯器會自動的隱式生成乙個拷貝建構函式和賦值運算子。但使用者可以使用delete來指定不生成拷貝建構函...