C 小菜2 拷貝建構函式

2021-06-18 22:45:57 字數 2851 閱讀 7925

拷貝建構函式(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 隱式 函式的形參有用到類物件卻沒有用引用或傳址技術時 函式的返回值是乙個物件也沒有應...