複製建構函式

2021-06-21 05:33:26 字數 1299 閱讀 2761

拷貝建構函式的標準寫法如下:

class

base

base(

const

base &b)

//上述寫法見得最多,甚至你認為理所當然。

那麼如果我們不寫成引用傳遞呢,而是值傳遞,那麼會怎樣?

class

base

base(

const

base b)

//編譯出錯:error c2652: 'base' : illegal copy constructor: first parameter must not be a 'base'

事實上,你可以從這個小小的問題認真搞清楚2件事:

1) 拷貝建構函式的作用就是用來複製物件的,在使用這個物件的例項來初始化這個物件的乙個新的例項。其實,個人認為不應該叫這些constructor(default constructor, copy constructor....)為建構函式,更佳的名字應該是"初始化函式"(見我的另一片文章).

2) 引數傳遞過程到底發生了什麼?

將位址傳遞和值傳遞統一起來,歸根結底還是傳遞的是"值"(位址也是值,只不過通過它可以找到另乙個值)!

i)值傳遞:

對於內建資料型別的傳遞時,直接賦值拷貝給形參(注意形參是函式內區域性變數);

對於類型別的傳遞時,需要首先呼叫該類的拷貝建構函式來初始化形參(區域性物件);如void foo(class_type obj_local){}, 如果呼叫foo(obj);  首先class_type obj_local(obj) ,這樣就定義了區域性變數obj_local供函式內部使用

ii)引用傳遞:

無論對內建型別還是類型別,傳遞引用或指標最終都是傳遞的位址值!而位址總是指標型別(屬於簡單型別), 顯然引數傳遞時,按簡單型別的賦值拷貝,而不會有拷貝建構函式的呼叫(對於類型別).

上述1) 2)回答了為什麼拷貝建構函式使用值傳遞會產生無限遞迴呼叫...

3). 如果不顯式宣告拷貝建構函式的時候,編譯器也會生成乙個預設的拷貝建構函式,而且在一般的情況下執行的也很好。但是在遇到類有指標資料成員時就出現問題了:因為預設的拷貝建構函式是按成員拷貝構造,這導致了兩個不同的指標(如ptr1=ptr2)指向了相同的記憶體。當乙個例項銷毀時,呼叫析構函式free(ptr1)釋放了這段記憶體,那麼剩下的乙個例項的指標ptr2就無效了,在被銷毀的時候free(ptr2)就會出現錯誤了, 這相當於重複釋放一塊記憶體兩次。這種情況必須顯式宣告並實現自己的拷貝建構函式,來為新的例項的指標分配新的記憶體。

上述3)回答了在類中有指標資料成員時,拷貝建構函式使用值傳遞等於白顯式定義了拷貝建構函式,因為預設的拷貝建構函式就是這麼幹的...

複製建構函式

今天回看了前面的內容,發現這一章掌握的不夠好,就重看了一遍,順便總結一下 無規律總結 複製建構函式用於複製物件,即可以初始化物件,也可以將複製得到的物件作為實參傳遞給函式,多用於初始化。當我們這樣寫 string null bulk 9 9 9 9 在建立null bulk時編譯器先呼叫string...

複製建構函式

呼叫複製建構函式的情形 在c 中,下面三種物件需要呼叫複製建構函式 1 乙個物件作為函式引數,以值傳遞的方式傳入函式體 2 乙個物件作為函式返回值,以值傳遞的方式從函式返回 3 乙個物件用於給另外乙個物件進行初始化 常稱為賦值初始化 4 編譯器生成臨時物件 一 乙個物件作為函式引數,以值傳遞的方式傳...

複製建構函式

所有需要分配系統資源的使用者定義的型別都需要乙個複製建構函式。所以在定義類的時候,是會自動的生成預設的複製建構函式的。複製建構函式是在建立物件時可用同一類的另乙個物件來初始化該物件。同乙個類的物件在記憶體中具有完全相同的結構,如果作為乙個整體進行複雜是完全可行的,這個複製過程只需要複製資料成員,而函...