在c++中, 建構函式,拷貝建構函式,析構函式和賦值函式(賦值運算子過載)是最基本不過的需要掌握的知識。 但是如果我問你「拷貝建構函式的引數為什麼必須使用引用型別?」這個問題, 你會怎麼回答? 或許你會回答為了減少一次記憶體拷貝? 很慚愧的是,我的第一感覺也是這麼回答。不過還好,我思索一下以後,發現這個答案是不對的。
原因:
如果拷貝建構函式中的引數不是乙個引用,即形如cclass(const cclass c_class),那麼就相當於採用了傳值的方式(pass-by-value),而傳值的方式會呼叫該類的拷貝建構函式,從而造成無窮遞迴地呼叫拷貝建構函式。因此拷貝建構函式的引數必須是乙個引用。
需要澄清的是,傳指標其實也是傳值,如果上面的拷貝建構函式寫成cclass(const cclass* c_class),也是不行的。事實上,只有傳引用不是傳值外,其他所有的傳遞方式都是傳值。
先從乙個小例子開始:(自己測試一下自己看看這個程式的輸出是什麼?)
#includeusing namespace std;
class cexample
; 會呼叫string的拷貝建構函式。
如果在沒有顯式宣告建構函式的情況下,編譯器都會為乙個類合成乙個預設的建構函式。如果在乙個類中宣告了乙個建構函式,那麼就會阻止編譯器為該類合成預設的建構函式。和建構函式不同的是,即便定義了其他建構函式(但沒有定義拷貝建構函式),編譯器總是會為我們合成乙個拷貝建構函式。
另外函式的返回值是不是引用也有很大的區別,返回的不是引用的時候,只是乙個簡單的物件,此時需要呼叫拷貝建構函式,否則,如果是引用的話就不需要呼叫拷貝建構函式。
#includeusing namespace std;
class a
a(const a& other) //建構函式過載
a(a other)
void print()
{ cout<答案:編譯錯誤。在複製建構函式中傳入的引數是a的乙個例項。由於是傳值,把形參拷貝到實參會呼叫複製建構函式。因此如果允許複製建構函式傳值,那麼會形成永無休止的遞迴並造成棧溢位。因此c++的標準不允許複製建構函式傳值引數,而必須是傳引用或者常量引用。在visual studio和gcc中,都將編譯出錯。
拷貝建構函式的引數型別必須是引用
在c 中,建構函式,拷貝建構函式,析構函式和賦值函式 賦值運算子過載 是最基本不過的需要掌握的知識。但是如果我問你 拷貝建構函式的引數為什麼必須使用引用型別?這個問題,你會怎麼回答?或許你會回答為了減少一次記憶體拷貝?很慚愧的是,我的第一感覺也是這麼回答。不過還好,我思索一下以後,發現這個答案是不對...
拷貝建構函式的引數型別必須是引用
在c 中,建構函式,拷貝建構函式,析構函式和賦值函式 賦值運算子過載 是最基本不過的需要掌握的知識。但是如果我問你 拷貝建構函式的引數為什麼必須使用引用型別?這個問題,你會怎麼回答?或許你會回答為了減少一次記憶體拷貝?很慚愧的是,我的第一感覺也是這麼回答。不過還好,我思索一下以後,發現這個答案是不對...
C C 中拷貝建構函式的引數型別必須是引用
在c 中,建構函式,拷貝建構函式,析構函式和賦值函式 賦值運算子過載 是最基本不過的需要掌握的知識。但是如果我問你 拷貝建構函式的引數為什麼必須使用引用型別?這個問題,你會怎麼回答?或許你會回答為了減少一次記憶體拷貝?很慚愧的是,我的第一感覺也是這麼回答。不過還好,我思索一下以後,發現這個答案是不對...