1,什麼是拷貝構造函數
拷貝構造函數有兩個含義:
首先,它是一個構造函數,當建立一個新對象時,系統自動調用它;
其次,它将一個已經定義過的對象的資料成員逐一對應的複制給新對象;
如果一個類沒有顯式定義拷貝構造函數,c++編譯器可以為該類産生一個預設的拷貝構造函數。這個預設的拷貝構造函數采用c的方式,将拷貝對象的記憶體一個位元組一個位元組的拷貝到拷貝對象的記憶體中(記憶體拷貝);
2,拷貝構造函數的作用
(1)建立一個新對象,并将一個已存在的對象拷貝到這個新對象;
(2)對象的值做參數(将實參對象拷貝到形參對象);
(3)函數傳回一個對象(拷貝傳回的一個對象給一個臨時對象);
3,為什麼需要拷貝構造函數
我們往往會忽略為一個類顯式地提供拷貝構造函數。此時c++編譯器可以為該類産生一個預設的拷貝構造函數。這個預設的拷貝構造函數采用c的方式,将拷貝對象的記憶體一個位元組一個位元組的拷貝到拷貝對象的記憶體中(記憶體拷貝)。這樣一來,新對象和老對象的記憶體映像是一模一樣的,我們可以說,新對象是老對象的“克隆體”;
在一般情況下,這個預設的拷貝構造函數工作得很好,但是,在一些特殊的情況下,它卻表現得有問題。
請看下面的例子:
我們需要統計一個類在程式運作過程中一共執行個體化出對少個對象。這個工作我們可以在類中加入一個靜态變量,并且在該類的構造函數中自增該變量,然後在析構函數中減計數。很明顯,如果計數以0開始,那麼程式結束時以0結尾。
運作結果:
in constructor...
point count=1
in fun()...
point count=1,此時已經出錯了,因為此時記憶體中不僅存在着p1對象,還存在着臨時對象形參p;
after object destroyed...
point count=0
after point2 create...
point count=-1
point count=-2
解決問題的方法相當直覺,就是為point類提供一個顯示 的拷貝構造函數。
point count=1 p1形成
..........................................................
in copy constructor...
point count=2
point count=2 形參p拷貝實參p1的結果
.........................................................
point count=3 p2接受fun傳回的結果
........................................................
point count=2 形參p銷毀
point count=2 p2形成
point count=1 p2銷毀
point count=0
p1銷毀