注意:該作者部落格已遷移至如果乙個建構函式的第乙個引數是自身類型別的引用,且任何額外的引數都有預設值,則此建構函式是拷貝建構函式。(c++ premier裡的定義)
拷貝建構函式應用的場景:
預設拷貝建構函式
class ctest
~ctest()
};void
test
(ctest obj)
intmain()
這個程式執行的結果為:
construct
discontruct
discontruct
當 testobj 以值傳遞的方式傳入test函式時,此時會生成乙個ctest型別的臨時變數,但是此時編譯器採用的是位拷貝(按位元組複製)的方式,呼叫預設拷貝建構函式,並不呼叫 ctest類的建構函式。
對於類中普通的成員變數,如int, double, char等,c++提供預設的拷貝建構函式,我們可以不用寫拷貝建構函式。
如果類中成員有*指標(深拷貝,淺拷貝問題),那麼我們就需要寫自己的拷貝建構函式。
例
若此時定義物件cexample obj1;並且obj1有指向動態分配的記憶體obj1.init(40)。
現在用obj1來初始化obj2,cexample obj2=obj1,則此時呼叫的是預設拷貝建構函式,複製所有成員的值,所以obj1.pbuffer=obj2.pbuffer,兩個物件裡的指標指向了同一塊記憶體。
如果obj1修改pbuffer指向記憶體裡的資料,則obj2訪問pbuffer指向的資料也會發生變化,這顯然不是我們想要的結果。(需要讓它們互不干擾)
所以我們要自己寫拷貝建構函式(不是複製指標,而是複製指標指向的動態記憶體裡的內容)。如下圖:
;此時呼叫test1的拷貝建構函式初始化物件test2
但是對於下面的表示式:呼叫的是過載的賦值運算子
ctest test1,test2;
test2 = test1;
拷貝建構函式和賦值的區別同樣,編譯器為我們的類提供預設的賦值符「=」
預設」=「的惡果
所以當有動態分配的記憶體時,要過載賦值運算子
拷貝建構函式與賦值運算子過載
拷貝建構函式 只有單個形參,該形參是對本類型別物件的引用 一般常用const修飾 在用已存在的類型別物件建立新物件時由編譯器自動呼叫。1.拷貝建構函式是建構函式的乙個過載形式 class date date const date d private int year int month int da...
拷貝構造與過載賦值運算子
編譯器預設的拷貝建構函式,發生的是memberwise initialization 成員逐一初始化 類的成員變數被逐一複製。而預設賦值運算子,也是逐一複製成員變數。一旦成員變數中,有程式設計師在heap開闢的空間 指標,new 使用預設拷貝建構函式就會引起淺拷貝和深拷貝的問題。include us...
拷貝構造與賦值運算子過載(順序)
other l類型別 找到合適的建構函式生成該類的物件 如果找不到例項化物件失敗 隱式呼叫建構函式 顯示呼叫函式 無名物件 零時物件 賦值運算子過載函式 分為3步 第一步 判斷是不是自身賦值 防止失敗出錯 第二步 釋放this指標所指的 外部 空間的大小 第三步重新分配空間 拷貝資料 物件的生存週期...