C++ 拷貝構造函數
作者 : 卿篤軍
1)定義:拷貝構造函數,是一種特殊的構造函數。它由編譯器調用來完畢一些基於同一類的其它對象的構建及初始化。
其唯一的形參必須是引用,但並不限制為const,一般普遍的會加上const限制。
此函數經經常使用在函數調用時用戶定義類型的值傳遞及返回。拷貝構造函數要調用基類的拷貝構造函數和成員函數。假設能夠的話,它將用常量方式調用,另外,也能夠用很量方式調用。
2)調用拷貝構造函數的情形:
在C++中。以下三種對象須要調用拷貝構造函數(有時也稱“復制構造函數”):
a) 一個對象作為函數參數,以值傳遞的方式傳入函數體;
b) 一個對象作為函數返回值,以值傳遞的方式從函數返回;
c) 一個對象用於給另外一個對象進行初始化(常稱為賦值初始化);
假設在前兩種情況不使用拷貝構造函數的時候。就會導致一個指針指向已經被刪除的內存空間。對於第三種情況來說,初始化和賦值的不同含義是拷貝構造函數調用的原因。其實,拷貝構造函數是由普通構造函數和賦值操作符共同實現的。描寫敘述拷貝構造函數和賦值運算符的異同的參考資料有非常多。
通常的原則是:①對於凡是包括動態分配成員或包括指針成員的類都應該提供拷貝構造函數;②在提供拷貝構造函數的同一時候。還應該考慮重載"="賦值操作符號。原因詳見後文。
拷貝構造函數必須以引用的形式傳遞(參數為引用值)。其原因例如以下:當一個對象以傳遞值的方式傳一個函數的時候。拷貝構造函數自己主動的被調用來生成函數中的對象。假設一個對象是被傳入自己的拷貝構造函數,它的拷貝構造函數將會被調用來拷貝這個對象這樣復制才幹夠傳入它自己的拷貝構造函數,這會導致無限循環直至棧溢出(Stack Overflow)。除了當對象傳入函數的時候被隱式調用以外。拷貝構造函數在對象被函數返回的時候也相同的被調用。
(以上文字段來自百度百科拷貝構造函數)
3)另外須要提一下的是explicit:
C++提供了keywordexplicit,能夠阻止不應該同意的經過轉換構造函數進行的隱式轉換的發生。
聲明為explicit的構造函數不能在隱式轉換中使用。
#include <iostream> using 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++ 拷貝構造函數
#include <iostream> using 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) ..."<<endl; } //拷貝構造函數 Cpy::Cpy(Cpy &p) { m_nA = p.m_nA; m_douB = p.m_douB; cout<<"Tip : Cpy::Cpy(Cpy &p) ..."<<endl; } //外部函數,返回值為一個類對象. Cpy fn() { cout<<"Tip : Cpy fn() ..."<<endl; Cpy buf; return buf; } int main() { Cpy a; //調用構造函數 Cpy b(a); //調用拷貝構造函數 Cpy c = a; //調用拷貝構造函數 fn(); //return時,調用拷貝構造函數 return 0; }執行結果:
參考文獻:百度百科,拷貝構造函數。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日
C++ 拷貝構造函數