構造函式作用
初始化對象的數據成員
規則:
構造函式與類同名且無返回值,在對象實例化時自動調用
構造函式可以有多個重載形式
實例化對象時僅用到一個構造函式
當用戶沒有定義構造函式時,編譯器自動生產一個構造函式
該類對象被創建時,編譯系統對象分配記憶體空間,並自動調用該構造函式,由構造函式完成成員的初始化工作。
編譯系統為對象的每個數據成員(m_strName)分配記憶體空間,並調用構造函式School()自動地初始化對象的m_strName值設定為"bullworth"
構造函式種類
無參數構造函式
1.如果創建一個類你沒有寫任何構造函式,則系統會自動生成默認的無參構造函式,函式為空,什麼都不做
2.只要你寫了一個下面的某一種構造函式,系統就不會再自動生成這樣一個默認的構造函式,如果希望有一個這樣的無參構造函式,則需要自己顯示地寫出來
一般構造函式(也稱重載構造函式)
1.一般構造函式可以有各種參數形式,一個類可以有多個一般構造函式,函式名稱相同,參數可辨(c++重載函式要求),如你還可以寫一個 Sudent( int num)的構造函式
2.創建對象時根據傳入的參數不同調用不同的構造函式
拷貝構造函式(也稱複製構造函式)
定義方式:(const 類名 & 變數名)
拷貝構造函式參數為類對象本身的引用,用於將已存在對象的數據成員的值複製一份到新創建的對象中
若沒有顯式的拷貝構造函式,則系統會默認創建一個拷貝構造函式,但當類中有指針成員時,由系統默認創建該複製構造函式會存在風險,具體原因請參閱附錄1
拷貝構造函式調用時機:
a.對象需要通過另外一個對象進行初始化
b.對象以值傳遞的方式從函式返回
c.對象以值傳遞的方式傳入函式參數
引用符號後的別名可省略 例:
1.拷貝構造函式參數為類對象本身的引用,用於將已存在對象的數據成員的值複製一份到新創建的對象中
2.若沒有顯式的拷貝構造函式,則系統會默認創建一個拷貝構造函式,但當類中有指針成員時,由系統默認創建該複製構造函式會存在風險,具體原因請參閱附錄1
3.拷貝構造函式調用時機:
a.對象需要通過另外一個對象進行初始化
b.對象以值傳遞的方式從函式返回
c.對象以值傳遞的方式傳入函式參數
4.引用符號後的別名可省略 例:
類型轉換構造函式
根據一個指定的類型的對象創建一個本類的對象
例如:下面將根據一個sting類型的對象創建了一個String對象
下面使用上面定義的類對象來說明各個構造函式的用法:
將"Jack"創建為一個本類的臨時對象,然後調用等號運算符重載,將該臨時對象賦值給d
淺拷與深拷貝
上面提到,如果沒有自定義複製構造函式,則系統會創建默認的複製構造函式,但系統創建的默認複製構造函式只會執行“淺拷貝”,即將被拷貝對象的數據成員的 值一一賦值給新創建的對象,若該類的數據成員中有指針成員,則會使得新的對象的指針所指向的地址與被拷貝對象的指針所指向的地址相同,delete該指針 時則會導致兩次重複delete而出錯。下面是示例:
【淺拷貝與深拷貝】
結果導致 man 和 woman 的指針都指向了同一個地址,函式結束析構時同一個地址被delete兩次。
下面自己設計複製構造函式,實現“深拷貝”,即不讓指針指向同一地址,而是重新申請一塊記憶體給新的對象的指針數據成員。
則新創建的對象的m_pName與原對象chs的m_pName不再指向同一地址了