就類物件而言,相同型別的類物件是通過拷貝建構函式來在物件初始化期間完成整個複製過程的。
拷貝建構函式是一種特殊的建構函式,函式的名稱必須和類名稱一致,它的唯一的乙個引數是本型別的乙個引用變數,該引數是const型別,不可變的。例如:類t的拷貝建構函式的形式為t(const t& t)。
當用乙個已初始化過了的自定義類型別物件去初始化另乙個新構造的物件的時候,拷貝建構函式就會被自動呼叫。也就是說,當類的物件需要拷貝時,拷貝建構函式將會被呼叫。以下情況都會呼叫拷貝建構函式:
乙個物件以值傳遞的方式傳入函式體
乙個物件以值傳遞的方式從函式返回
乙個物件需要通過另外乙個已存在的物件進行初始化。
如果沒有自己實現拷貝建構函式,編譯器會自動生成乙個預設的拷貝建構函式,預設的拷貝建構函式完成物件之間的位拷貝,又稱淺拷貝。對於任何含有指標變數的類,預設的(淺)拷貝函式注定出錯。
淺拷貝只是簡單地將乙個物件記憶體的資料複製給另乙個物件。在類中含有指標變數狀況下,指標變數需要動態開闢堆記憶體,如果實行位拷貝,也就是把物件裡的值完全複製給另乙個物件,如a=b。這時,如果b中有乙個成員變數指標已經申請了記憶體,那a中的那個成員變數也指向同一塊記憶體。這就出現了問題:當b把記憶體釋放了(如:析構),這時a內的指標就是野指標了,出現執行錯誤。
深拷貝和淺拷貝可以簡單理解為:如果乙個類擁有資源,當這個類的物件發生複製過程的時候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝。
下面實現了乙個拷貝建構函式的例子:
class cgoods
//拷貝建構函式
cgoods(const cgoods& good)
cgoods(const cgoods& good)
; data(int _data)
:data(_data)
data& operator=(const int _data) //引數型別不是本類或本類的引用
我們提供了乙個帶int型引數的賦值運算子過載函式,data2 = 1;一句呼叫了該函式,如果編譯器不再提供預設的賦值運算子過載函式,那麼,data3 = data2;一句將不會編譯通過,但我們看到事實並非如此。說明此種情況下,系統提供了乙個預設的賦值運算子過載函式。
class cgoods
cgoods(const cgoods& good)
{ cout<
建構函式,拷貝建構函式,析構函式,賦值運算子過載
1 建構函式 定義 是乙個特殊的成員函式,名字與類名相同,建立類型別物件時,由編譯器自動呼叫,在物件的生命週期內有且只呼叫一次,以保證每個資料成員都有乙個合適的初始值。特性 1 函式名與類名相同。2 沒有返回值。3 有初始化列表 可以不用 4 建構函式可以過載,實參決定了呼叫那個建構函式。5 如果沒...
拷貝建構函式和賦值運算子
把引數傳遞給函式有三種方法,一種是值傳遞,一種是傳位址,還有一種是傳引用。前者與後兩者不同的地方在於 當使用值傳遞的時候,會在函式裡面生成傳遞引數的乙個副本,這個副本的內容是按位從原始引數那裡複製過來的,兩者的內容是相同的。當原始引數是乙個類的物件時,它也會產生乙個物件的副本,不過在這裡要注意。一般...
拷貝建構函式與賦值運算子
物件的 生命週期 管理意味著完全地控制物件的誕生 繁殖和消亡的過程。使用拷貝建構函式和賦值運算子,可以更快的進行物件的繁殖操作。拷貝建構函式是一種建構函式,其原型類似於 classname const classname x 賦值建構函式的作用就是建立乙個物件,該物件是同乙個類中已有物件的精確副本。...