C 拷貝建構函式和賦值運算子

2021-10-25 08:39:47 字數 1935 閱讀 8095

這篇文章主要介紹拷貝建構函式和賦值運算子的區別,以及在什麼時候呼叫拷貝建構函式,什麼情況下呼叫賦值運算子。

在預設情況下(使用者沒有定義,但是也沒有顯示的刪除),編譯器會自動隱式生成乙個拷貝建構函式和賦值運算子,但使用者可以使用delete來指定不生成拷貝建構函式和賦值運算子,這樣的物件就不能通過值傳遞,也不能進行賦值運算

#include

using namespace std;

class person

person

(const person& p)

= delete;

person& operator=

(const person& p)

= delete;

void

setname

( string strname )

void

setage

(int nage)

private:

int age;

string name;};

intmain()

上面定義的類person顯式的刪除了拷貝建構函式和賦值運算子,在需要呼叫拷貝建構函式或者賦值運算子的地方,會提示無法呼叫該函式,它是已刪除的函式。

還有一點需要注意的是,拷貝建構函式必須以引用的方式傳遞引數,這是因為,在值傳遞給乙個函式的時候,會呼叫拷貝建構函式生成函式的實參,如果拷貝建構函式的引數仍然是以值的方式,就會無限迴圈的呼叫下去,直到函式的棧溢位。

拷貝建構函式和賦值運算子的行為比較相似,都是將乙個物件的值複製給另乙個物件,但是其結果卻有些不同,拷貝建構函式使用傳入物件的值生成乙個新的物件的例項,而賦值運算子是將物件的值複製給乙個已經存在的例項。這種區別從兩者的名字也能輕易的分辨出來,拷貝建構函式也是一種建構函式,那麼它的功能就是建立乙個新的物件例項;賦值運算子是執行某種運算,將乙個物件的值複製給另乙個物件(已經存在的)。呼叫的是拷貝建構函式還是賦值運算子,主要是看是否有新的物件例項產生,如果產生了新的物件例項,那呼叫的就是拷貝建構函式;如果沒有,那就是對已有的物件賦值,呼叫的是賦值運算子。

呼叫拷貝建構函式主要有以下場景:

1:物件作為函式的引數,以值傳遞的方式傳給函式。

2:物件作為函式的返回值,以值的方式從函式返回。

3:使用乙個物件給另乙個物件初始化。

**如下:

1:雖然使用了「=」,但是實際上使用物件p來建立了乙個新的物件p1.也就是產生了新的物件,所以呼叫的是拷貝建構函式。

2:首先宣告了乙個物件p2,然後使用複製運算子"=",將p的值賦值給p2,顯然是呼叫了賦值運算子,為乙個已經存在的物件賦值。

3:以值傳遞的方式將物件p2傳入函式f內,呼叫拷貝建構函式構建乙個函式f可用的實參

4:這條語句拷貝建構函式和賦值運算子都呼叫了。函式f1以值的方式返回乙個person物件,在返回時會呼叫拷貝建構函式建立乙個臨時物件tmp作為返回值;返回後呼叫賦值運算子將臨時物件tmp賦值給p2.

5:應該是首先呼叫拷貝建構函式建立臨時物件;然後再呼叫拷貝建構函式使用剛才建立的臨時物件建立新的物件p3,也就是會呼叫兩次拷貝建構函式。不過,編譯器也沒有那麼傻,應該是直接呼叫拷貝建構函式使用返回值建立了物件p3。

C 拷貝建構函式和賦值運算子

本文主要介紹了拷貝建構函式和賦值運算子的區別,以及在什麼時候呼叫拷貝建構函式 什麼情況下呼叫賦值運算子。最後,簡單的分析了下深拷貝和淺拷貝的問題。在預設情況下 使用者沒有定義,但是也沒有顯式的刪除 編譯器會自動的隱式生成乙個拷貝建構函式和賦值運算子。但使用者可以使用delete來指定不生成拷貝建構函...

拷貝建構函式和賦值運算子

把引數傳遞給函式有三種方法,一種是值傳遞,一種是傳位址,還有一種是傳引用。前者與後兩者不同的地方在於 當使用值傳遞的時候,會在函式裡面生成傳遞引數的乙個副本,這個副本的內容是按位從原始引數那裡複製過來的,兩者的內容是相同的。當原始引數是乙個類的物件時,它也會產生乙個物件的副本,不過在這裡要注意。一般...

拷貝建構函式和賦值運算子

來自 本文主要介紹了拷貝建構函式和賦值運算子的區別,以及在什麼時候呼叫拷貝建構函式 什麼情況下呼叫賦值運算子。最後,簡單的分析了下深拷貝和淺拷貝的問題。在預設情況下 使用者沒有定義,但是也沒有顯式的刪除 編譯器會自動的隱式生成乙個拷貝建構函式和賦值運算子。但使用者可以使用delete來指定不生成拷貝...