拷貝建構函式的引數為什麼是引用

2021-07-04 16:32:56 字數 2499 閱讀 4863

在c++中, 建構函式,拷貝建構函式,析構函式和賦值函式(賦值運算子過載)是最基本不過的需要掌握的知識。 但是如果我問你「拷貝建構函式的引數為什麼必須使用引用型別?」這個問題, 你會怎麼回答? 或許你會回答為了減少一次記憶體拷貝? 很慚愧的是,我的第一感覺也是這麼回答。不好還好,我有理性這個好品質。思索一下以後,發現這個答案是不對的。讓我來撕開(有點暴力,但是我喜歡,嘿嘿--齜牙)那件隱藏在真理外的小褲衩,讓它袒露在「登徒子」們的眼前吧。

先從乙個小例子開始:(自己測試一下自己看看這個程式的輸出是什麼?)

[c-sharp]view plain

copy

#include 

class

cexample  

cexample(const

cexample & ex) 

//拷貝建構函式

cexample& operator

= (const

cexample &ex)

//賦值函式(賦值運算子過載)

void

mytestfunc(cexample ex)  

};  

intmain()    

看這個例子的輸出結果:

constructor with argument//

cexample 

aaa(2);

constructor with argument

//cexample 

bbb(3)

;assignment operator

//

bbb = aaa;

copy constructor//

cexample 

ccc = aaa;

copy constructor 

如果你能一眼看出就是這個結果的話, 恭喜你,可以站起來扭扭屁股,不用再往下看了。

如果你的結果和輸出結果有誤差, 那拜託你謙虛的看完。

第乙個輸出:constructor with argument//

cexample 

aaa(2);

如果你不理解的話, 找個人把你拖出去痛打一頓,然後嘴裡還喊著「我是二師兄,我是二師兄.......」

第二個輸出:

constructor with argument

//

cexample 

bbb(3);

分析同第乙個

第三個輸出:assignment operator

//bbb = aaa;

第四個輸出:

copy constructor//

cexample 

ccc = aaa;

這兩個得放到一塊說。 肯定會有人問為什麼兩個不一致。原因是, bbb物件已經例項化了,不需要構造,此時只是將aaa賦值給bbb,只會呼叫賦值函式,就這麼簡單,還不懂的話,撞牆去! 但是ccc還沒有例項化,因此呼叫的是拷貝建構函式,構造出ccc,而不是賦值函式,還不懂的話,我撞牆去!!

第五個輸出:copy constructor 

實際上是aaa作為引數傳遞給bbb.mytestfunc(cexample ex), 即cexample ex = aaa;和第四個一致的, 所以還是拷貝建構函式,而不是賦值函式, 如果仍然不懂, 我的頭剛才已經流血了,不要再讓我撞了,你就自己使勁的再裝一次吧。

通過這個例子, 我們來分析一下為什麼拷貝建構函式的引數只能使用引用型別。

看第四個輸出: copy constructor//

cexample 

ccc = aaa;

構造ccc,實質上是ccc.cexample(aaa); 我們假如拷貝構造函式引數不是引用型別的話, 那麼將使得 ccc.cexample(aaa)變成aaa傳值給ccc.cexample(cexample ex),即cexample ex = aaa,因為 ex 沒有被初始化, 所以 cexample ex = aaa 繼續呼叫拷貝建構函式,接下來的是構造ex,也就是 ex.cexample(aaa),必然又會有aaa傳給cexample(cexample ex), 即 cexample ex = aaa;那麼又會觸發拷貝建構函式,就這下永遠的遞迴下去。

所以繞了那麼大的彎子,就是想說明拷貝建構函式的引數使用引用型別不是為了減少一次記憶體拷貝, 而是避免拷貝建構函式無限制的遞迴下去。

所以, 拷貝建構函式是必須要帶引用型別的引數的, 而且這也是編譯器強制性要求的

拷貝建構函式的引數為什麼必須是引用?

1 include2 include 3using namespace std 4class foo5 13 foo foo f ss f.ss 1417 foo operator const foo f1 1822 void test foo f2 2326 27 28int main 29 如果...

為什麼拷貝建構函式自己的引數必須是「引用型別」

書上解釋說 如果其引數不是引用型別,則呼叫永遠也不會成功 為了呼叫拷貝建構函式,我們必須拷貝它的實參,但為了拷貝實參,我們又需要呼叫拷貝建構函式,如此無限迴圈。我就乙個狀態 這是在說啥?把我自己搞糊塗了,這到底是什麼意思?分句來理解。第一句 為了呼叫拷貝建構函式,我們必須拷貝它的實參。這句話還是很容...

拷貝建構函式為什麼要用引用?

一 引用 1.概念 引用不是新定義乙個變數,而是給已經存在的變數取了個別名,編譯器不會為引用開闢記憶體空間,它和它引用的變數共用同一塊記憶體空間。2.和指標區別 引用在定義時必須初始化,指標沒有要求 引用在初始化時引用乙個實體後,就不能再引用其他實體,而指標可以在任何時候指向任何乙個同型別實體 沒有...