深入C++之對象構造析構

關於基類的幾個概念
虛基類:爲防止多繼承時,基類成員多份存在所使用的虛繼承方式(public virtual base),這個基類就被稱爲虛基類
抽象類:含有(或繼承)一個或多個純虛函數的類是抽象基類

抽象類(abstract class)的設計

抽象類一般隱含作爲基類的意思,所以也是抽象基類,抽象類構造函數何時應該被定義:

  • 數據成員的存在的情況下,一般爲與繼承類共用的數據成員,應該存在初始化數據成員的構造函數。
  • 亦或存在更上層的基類沒有默認的構造函數,需要顯式調用更上層次的構造函數。
這時構造函數設計爲protected足以滿足初始化的要求,就是繼承類需要調用其,同時符合抽象類不能存在實例對象的要求。

構造函數不能爲虛函數的原因有幾點:
1 對象實例的創建在構造函數調用之後,而虛函數的虛表的創建在構造函數之後。
2 創建對象的方式包含new,本身就決定了對象會直接調用本身構造函數,虛構造函數沒有存在的必要,等還有其他原因。


析構函數的設計
必須定義析構函數,無論是自定義或者編譯器生成,因爲在繼承類析構函數中存在BaseClass::~ BaseClass()這樣的靜態調用方式,注意這個代碼是編譯器生成的。
一個最合理的設計是,最上層的基類中析構函數應該聲明爲virtual類型,同時它不應該被定義爲純虛函數,因爲它總是被調用,而至於其是public或者protected則需要看情況,如果在基類中並且不被作爲某個繼承類的實例對象的引用,即在繼承類的外部沒有進行析構現象,則protected是合適的,但是最好將析構函數定義爲public根合理些。


防止對象的隱式轉換:使用 expict關鍵字進行限制隱式轉換。


對象構造與析構的幾點要求

1類的初始化構造順序
置於構造函數初始化列表中的對象必須是該類的基類或非靜態對象成員,而不能是基類的對象成員,基類的對象成員應該由基類進行初始化。

所以對繼承類對基類成員的構造操作無法影響到基類的構造操作,因爲基類的構造在繼承類之前,所以依賴於繼承類對基類成員的操作後進行的初始化工作需要放到繼承類的初始化完成後

2 對象與指針成員的內存管理
2.1 使用malloc後,對象構造的初始化工作必須手動進行。
2.2 同理malloc 後進行手動的初始化工作,同時在 free前進行手動的資源釋放工作,因爲沒有構造析構過程。所以合理的方法是使用new進行對象的動態創建
2.3 在傳遞對象的地方,常伴隨着對象的析構,所以必須重定義拷貝構造函數,與賦值函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章