作者 : 卿笃軍
1)定義:拷貝構造函數,是一種特殊的構造函數,它由編譯器調用來完成一些基於同一類的其他對象的構建及初始化。其唯一的形參必須是引用,但並不限制為const,一般普遍的會加上const限制。此函數經常用在函數調用時用戶定義類型的值傳遞及返回。拷貝構造函數要調用基類的拷貝構造函數和成員函數。如果可以的話,它將用常量方式調用,另外,也可以用非常量方式調用。
2)調用拷貝構造函數的情形:
在C++中,下面三種對象需要調用拷貝構造函數(有時也稱“復制構造函數”):
a) 一個對象作為函數參數,以值傳遞的方式傳入函數體;
b) 一個對象作為函數返回值,以值傳遞的方式從函數返回;
c) 一個對象用於給另外一個對象進行初始化(常稱為賦值初始化);
如果在前兩種情況不使用拷貝構造函數的時候,就會導致一個指針指向已經被刪除的內存空間。對於第三種情況來說,初始化和賦值的不同含義是拷貝構造函數調用的原因。事實上,拷貝構造函數是由普通構造函數和賦值操作符共同實現的。描述拷貝構造函數和賦值運算符的異同的參考資料有很多。
通常的原則是:①對於凡是包含動態分配成員或包含指針成員的類都應該提供拷貝構造函數;②在提供拷貝構造函數的同時,還應該考慮重載"="賦值操作符號。原因詳見後文。
拷貝構造函數必須以引用的形式傳遞(參數為引用值)。其原因如下:當一個對象以傳遞值的方式傳一個函數的時候,拷貝構造函數自動的被調用來生成函數中的對象。如果一個對象是被傳入自己的拷貝構造函數,它的拷貝構造函數將會被調用來拷貝這個對象這樣復制才可以傳入它自己的拷貝構造函數,這會導致無限循環直至棧溢出(Stack Overflow)。除了當對象傳入函數的時候被隱式調用以外,拷貝構造函數在對象被函數返回的時候也同樣的被調用。
(以上文字段來自百度百科拷貝構造函數)
3)另外需要提一下的是explicit:
C++提供了關鍵字explicit,可以阻止不應該允許的經過轉換構造函數進行的隱式轉換的發生。聲明為explicit的構造函數不能在隱式轉換中使用。
#includeusing namespace std; class A { public: A(int a){ m_a = a; } // explicit A(int a){ m_a = a; } //explicit:使構造函數不能對單個數字進行強制轉換 private: int m_a; }; int main() { A a(3); A b = 6; //相當於A b = A(6),將6強制轉換 return 0; }
注意:只有單個的數字才可以A b = 6; 這樣。但是不建議這麼使用。請按照上面的A a(3);方式使用。
示例:C++ 拷貝構造函數
#includeusing namespace std; class Cpy { public: Cpy(int nA = 0, double douB = 0.0); //構造函數 Cpy(Cpy &p); //拷貝構造函數 private: int m_nA; double m_douB; }; //構造函數 Cpy::Cpy(int nA, double douB) { m_nA = nA; m_douB = douB; cout<<"Tip : Cpy::Cpy(int nA, double douB) ..."< 運行結果:
參考文獻:百度百科,拷貝構造函數,http://baike.baidu.com/view/1266959.htm,2014年5月24日
百度百科,explicit,http://baike.baidu.com/view/2422253.htm,2014年5月24日
熊思的CSDN博客,C++構造函數,http://blog.csdn.net/u010056396/article/details/26623069,2014年5月24日