拷貝建構函式(copy constructor)是一種特殊的建構函式,用於拷貝乙個已存在的例項。
當乙個新變數通過另乙個物件建立,即在宣告時初始化,拷貝函式將會被呼叫。符合該要求的情況如下:
person q("mickey"); // constructoris used to build q.
person r(p); //copy constructor is used to build
r. person p = q; // copy constructor is used to initialize in declaration.
p = q; // assignment operator, no constructor or copy constructor.
注意,賦值操作並不會呼叫拷貝建構函式。除它以外,以上幾種情況拷貝建構函式都會呼叫。如果你沒有在類中定義拷貝建構函式,c++將會呼叫預設的拷貝建構函式。注意,預設拷貝建構函式的拷貝過程屬於淺拷貝(shallow copy)。關於淺拷貝,稍後我會詳解。
根據c++的標準,如果要定義乙個拷貝建構函式,必須按照以下四種標準,擇一編寫:
1. myclass( const myclass& other );
2. myclass( myclass& other );
3. myclass( volatile const myclass& other );
4. myclass( volatile myclass& other );
注意,以下幾種都不是正規寫法:
1. myclass( myclass *other );
2. myclass( const myclass *other );
3. myclass( myclass other );
如果你僅需要淺拷貝(shallowcopy),就無需自行編寫拷貝建構函式。與之對應,如果需要深拷貝(deep copy),那麼就必須編寫拷貝建構函式了。
在此,我先來解析淺拷貝和深拷貝的區別。
淺拷貝(shallow copy):
以b拷貝a的內容為例。淺拷貝的過程中,b只拷貝a的域值( field value)。如果a的域值是乙個記憶體位址,那麼,拷貝完成後,a、b指向同乙個位址。即a、b共享乙個元素。
深拷貝(deep copy)
深拷貝則是複製所有的內容。即把a指向位址包含的內容,全部複製給b,b仍指向之前的位址,但是該位址的內容與a位址包含的內容相同。
簡言之,淺拷貝複製了指標,深拷貝複製了指標內容。
淺拷貝的缺點在於,如果你修改了b指向位址的內容,a指向的內容同時也會被修改。深拷貝拷貝的缺點在於拷貝過程費時、費空間。
如果你因為要進行深拷貝而自行編寫了拷貝建構函式,那麼你同時需要編寫析構函式以及過載賦值運算子。
下面是乙個拷貝建構函式的例子:
class myclass
;myclass::myclass( const myclass& other ) : x( other.x ), c( other.c ), s( other.s ) {}
這裡強調一下為何建構函式的引數使用了const。使用const 可以保證拷貝建構函式不會修改傳入的引用。但如果引數是 non-const,那麼引數不能是臨時物件( temporary object)。臨時物件,就是沒有變數名的物件例項。
以下述**為例:
// improperly declared function: parameter should be const reference:
void print_me_bad( std::string& s )
// properly declared function: function has no intent to modify s:
void print_me_good(const std::string& s )
std::string hello( "hello" );
print_me_bad( hello ); // compiles ok; hello is not a temporary
print_me_bad( std::string( "world" ) ); // compile error; temporary object
print_me_bad( "!" );
// compile error; compiler wants to construct temporary std::string from const char*
print_me_good( hello );
// compiles ok
print_me_good( std::string( "world" ) ); // compiles ok
print_me_good( "!" );
// compiles ok
因為print_me_bad沒有使用const引數,所以無法向它傳入臨時物件。
C 建構函式2 拷貝建構函式
前言 拷貝建構函式是c 中的重點之一,在這裡對其知識進行乙個簡單的總結。在c 中,對於內建型別的變數來說,在其建立的過程中用同型別的另乙個變數來初始化它是完全可以的,如 1 int value 100 2 int new value value 在變數new value建立的同時用同型別的變數val...
C 建構函式 拷貝建構函式
建構函式 class base private int m var 建構函式無返回值型別,函式名和型別相同。拷貝建構函式傳遞引數為引用。1 class base2 7 拷貝建構函式 8 base base ref m var ref m var 9 11 private 12 intm var 13...
C 拷貝建構函式
1 什麼時候會用到拷貝建構函式?當任何你想影印東西的時候,而不管東西被影印成什麼樣子。即任何你想利用乙個已有的類例項給另乙個類例項賦值時,這種賦值可能是顯式的,也可能是隱式的 顯式 classa 1 class 2 隱式 函式的形參有用到類物件卻沒有用引用或傳址技術時 函式的返回值是乙個物件也沒有應...