為什麼複製建構函式的形參必須是引用型別?

2021-06-12 21:49:45 字數 1888 閱讀 8105

複製建構函式只有乙個引數,由於在建立時傳入的是同種型別的物件,所以乙個很自然的想法是將該型別的物件作為引數,像這樣:

sample (sample a);

不幸的是,即使是這樣樸實無華的宣告也隱含了乙個微妙的錯誤,呵,我們來看看:當某個時候需要以乙個sample物件的值來為乙個新物件進行初始化時,編譯器會在各個過載的建構函式版本(如果有多個的話)搜尋,它找到的這個版本,發現宣告引數與傳入的物件一致,因此該建構函式將會被呼叫。目前為止,一切都在我們的意料之中,但問題很快來了:該函式的引數我們使用了值傳遞的方式,按照前面的分析,這需要呼叫複製建構函式,於是編譯器又再度搜尋,最後當然又找到了它,於是進行呼叫,但同樣地,傳參時又要進行複製,於是再呼叫...這個過程周而復始,每次都是到了函式入口處就進行遞迴,直到堆疊空間耗盡,程式崩潰...

由是觀之,值傳遞看來是行不通的了;我想c語言的使用者這時很快會反應到與值傳遞對應的方式:位址傳遞(傳址),於是宣告變為這樣:

sample sample *p);

只作為一般的建構函式,它應該可以執行得很好,但別忘了我們要提供的是複製建構函式,它要求能夠接受乙個同型別物件,像這樣:

sample a;

sample b(a);

而不是接受指標:

sample a;

sample b(&a);   // 還要取位址?當然,它可以正確執行,但...

雖然在初始化物件時可以像上面一樣人為加乙個取址符,但在函式引數表中(或者函式返回)進行值傳遞時,編譯器可不知道在找不著合適定義的情況下牽就選擇你的指標版本。

只有單個形參,而且該形參是對本類型別物件的引用(常用 const 修飾),這樣的建構函式稱為複製

建構函式

複製建構函式可用於:

. 根據另乙個同型別的物件顯式或隱式初始化乙個物件

. 複製乙個物件,將它作為實參傳給乙個函式

. 從函式返回時複製乙個物件

. 初始化順序容器中的元素

. 根據元素初始化式列表初始化陣列元素

當用於類型別物件時,初始化的複製形式和直接形式有所不同:直接初始化直接呼叫與實參匹配的構

造函式,複製初始化總是呼叫複製建構函式

對於類型別物件,只有指定單個實參或顯式建立乙個臨時物件用於複製時,才使用複製初始化

當形參或返回值為類型別時,由複製建構函式進行複製

如果沒有為類型別陣列提供元素初始化式,則將用預設建構函式初始化每個元素

如果我們沒有定義複製建構函式,編譯器就會為我們合成乙個

與合成的預設建構函式不同,即使我們定義了其他建構函式,也會合成複製建構函式

合成複製建構函式的行為是,執行逐個成員初始化,將新物件初始化為原物件的副本

雖然一般不能複製陣列,但如果乙個類具有陣列成員,則合成複製建構函式將複製陣列,複製陣列時

合成複製建構函式將複製陣列的每乙個元素

逐個成員初始化最簡單的概念模型是,將合成複製建構函式看作這樣乙個建構函式:其中每個資料成

員在建構函式初始化列表中進行初始化

雖然也可以定義接受非 const 引用的複製建構函式,但形參通常是乙個 const 引用

因為用於向函式傳遞物件和從函式返回物件,該建構函式一般不應設定為 explicit

有些類必須對複製物件時發生的事情加以控制,這樣的類經常有乙個資料成員是指標,或者有成員表

示在建構函式中分配的其他資源,而另一些類在建立新物件時必須做一些特定工作,這兩種情況下,

都必須定義複製建構函式

為了防止複製,類必須顯式宣告其複製建構函式為 private

類的友元和成員仍可以進行複製,如果想要連友元和成員中的複製也禁止,就可以宣告乙個

(private)複製建構函式但不對其定義

一般來說,最好顯式或隱式定義預設建構函式和複製建構函式,只有不存在其他建構函式時才合成默

認建構函式。如果定義了複製建構函式,也必須定義預設建構函式。

為什麼拷貝建構函式的形參必須是引用型別?

複製建構函式只有乙個引數,由於在建立時傳入的是同種型別的物件,所以乙個很自然的想法是將該型別的物件作為引數,像這樣 sample sample a 不幸的是,即使是這樣樸實無華的宣告也隱含了乙個微妙的錯誤,呵,我們來看看 當某個時候需要以乙個sample物件的值來為乙個新物件進行初始化時,編譯器會在...

c 複製建構函式形參為什麼是const引用

使用反證法即可證明。如果使用值傳遞形式構造類的複製建構函式,在使用a初始化t時,呼叫複製建構函式。該函式為值傳遞形參,需要對a進行複製操作,又會呼叫複製建構函式,而複製建構函式是值傳遞,又需要進行複製操作 無限迴圈下去。顯然值傳遞是不可行的,解決辦法就是採用引用傳遞。class base base ...

c 中為什麼複製建構函式的形參必須是乙個引用

class myclass 乙個簡單的類 myclass a 這樣通過myclass 的建構函式建立了乙個myclass的物件,同樣樣在函式傳參的時候 void fun myclass a 引數a也必須呼叫myclass的建構函式來生成物件,那麼在乙個類的拷貝建構函式中寫出了這樣形式 class m...