一、拷貝構造函數:
格式: A(const A& a);
總結:
系統為對象B分配了內存並完成了與對象testA的復制過程,就類對象而言,相同類型的類對象是通過拷貝構造函數來完成整個復制過程的。
1.拷貝構造函數的使用:
A testA;
A B = testA;
2.析構的先后順序:
程序結束,析構的時候,先析構了B,后析構了testA.
二、拷貝構造函數的調用時機
1、當函數的參數為類的對象時;
調用copy_constructor_fun(A aA)時,會產生以下幾個重要步驟:
(1)、A對象傳入形參時,會先產生一個臨時變量Temp;
(2)、然后調用拷貝構造函數把A的值給Temp。
(3)、等copy_constructor_fun()指向完畢后,析構掉Temp。
2、函數的返回值是類的對象
3、對象需要另外一個對象進行初始化
A testA(100);
A B = testA;
或者:
A C(testA);
三、深拷貝和淺拷貝
1、默認拷貝構造函數
2、淺拷貝
簡單的值復制,比如上面幾個例子,都是淺拷貝,默認的拷貝構造函數都是淺拷貝。
3、深拷貝
深拷貝主要用於類中有指針成員變量時,防止析構的時候指針懸掛現象。
因為默認的拷貝構造函數只是簡單的值復制,如果存在指針變量,相當於兩個指針指向同一塊內存地址,析構的時候,該塊內存地址會被析構兩遍,那么當第一次被釋放之后,后面指向該內存的指針就會存在懸掛的現象。
深拷貝主要是為拷貝的類對象中的指針變量開辟新的內存空間,這樣釋放的時候,就不會出現懸掛現象。
寫明顯示的深拷貝構造函數:
四、總結
1.為什么拷貝構造函數的參數必須是引用傳遞,而不是值傳遞
防止遞歸調用。
2、拷貝構造函數的作用
用來復制對象的,使用以一個對象的實例來初始化這個對象的一個新的實例。
3、對一個類A,如果一個構造函數的第一個參數是下列之一:
1) A&
2) const A&
3) volatile A&
4) const volatile A&
且沒有其他參數或者其他參數都有默認值,那么這個函數是拷貝構造函數。
4、一個類中可以存在多余一個的拷貝構造函數嗎?
答: 類中可以存在超過一個拷貝構造函數。
注意,如果一個類中只存在一個參數為 X& 的拷貝構造函數,那么就不能使用const X或volatile X的對象實行拷貝初始化.
如果一個類中沒有定義拷貝構造函數,那么編譯器會自動產生一個默認的拷貝構造函數。
這個默認的參數可能為 X::X(const X&)或 X::X(X&),由編譯器根據上下文決定選擇哪一個。
5、構造函數可以重載,析構函數不可以重載。
6、禁止拷貝,禁止賦值操作符
將拷貝構造函數和賦值操作符聲明為private即可。