C++Primer學習筆記(代碼重用)

 在一個自定義的類中,如果這個類的成員裏面包含了其他類的對象,就說明這個類是包含了其他類對象成員的類。包含關係和繼承關係不同,包含關係只是包含了其成員對象的實現,但是沒有包含這個對象所能夠調用的它所屬類的方法。如果我想要調用這些方法的話,要在自定義類中的成員方法裏添加調用這些方法的語句。

1、初始化被包含的對象成員 

在初始化類中成員的時候,可以用成員初始化列表來完成操作,初始化內置類型和其他類對象類型的成員都直接使用成員名(值)這種形式即可,他們會自動調用相應類中的合適的構造函數,但是在初始化有繼承的對象的時候,就要在成員初始化列表裏面利用作用域標識符的形式調用基類的構造函數。如果在類的構造函數中沒有使用成員初始化列表的方式來初始化類中類對象類型的成員的話,那麼C++在初始化這些成員時就會調用他們類中的默認的構造函數來初始化他們。


成員初始化列表中的初始化順序,與在初始化 列表中的順序沒有關係,和他們在類中聲明的順序有關係。


2、使用被包含對象成員的接口

新定義類中的數據成員都被放在類私有部分中,這些成員中的類對象的成員的接口也變得不是公有的,但是卻可以在自己定義的類方法中使用這些對象成員所在類的接口。


3、私有繼承

私有繼承意味着基類當中所有的數據成員還有公有接口在子類中都變成了私有的,所以在子類中,只能通過子類的公有方法去訪問私有部分。私有繼承和包含對象類型的成員一樣,都是隻獲得對象的實現,但是不獲得對象的接口,也就是不能把對象的方法作爲我們新定義的類的公有方法。私有繼承和包含一個類對象成員都不能夠直接調用對象的方法,要通過新定義類中的成員方法纔可以進行調用。


包含對象成員是顯式的包含了一個有名字的類對象成員,但是私有 繼承將會包含一個無名稱的對象成員。在新定義類中的構造函數的實現時,在初始化類對象的成員,如果是包含的,那麼可以直接使用成員名(值)的方式,編譯器會自動爲我們調用該對象對象的構造函數,但是如果是私有繼承的話,那麼就只能夠顯式的調用相應的構造函數了。


在包含對象的時候,可以在新定義類中的公有方法中使用對象名來調用該對象所在類的公有方法,在私有 繼承的時候,由於私有繼承包含的是無名的對象成員,所以我們想要調用基類的方法的 時候,可以使用作用域標識符限定的方式來調用。


在私有繼承的時候,基類當中的方法只能夠在派生類 中的公有方法中使用。如果我想在派生類外中使用的話,我可以吧基類中要使用的方法,放在子類中定義的一個公有方法裏,或者直接在子類的公有部分利用using指令來引用基類當中的某一個比較特殊的方法。


4、多重繼承

  一般來說,多重繼承也就是多重公有繼承,多重繼承會導致子類有多個基類。因爲子類繼承基類將會繼承下來基類對象的部分,假設A是基類,BC兩個派生類繼承自A,作爲基類出現,D繼承自B和C兩個類,所以在將子類D對象的地址賦值給基類A對象的指針的時候,可能會出現二義性,因爲D類對象繼承了BC兩個類的部分,而BC兩個類的對象部分均有A類的部分,所以說,不知道改把哪一部分的基類地址賦值給A類指針。所以這時候就要在D類對象的地址前面進行強制類型轉換。



如果一個子類是繼承自多個基類,並且這多個基類都有一個共同的基類。那麼爲了避免 上面出現的最底下的子類 對象有兩份基類的對象的拷貝,可以將起始的那個基類聲明爲虛基類。這樣的話,子類對象只包含一個基類對象部分。從本質上講,第二層的兩個基類繼承自起始基類的時候,不再各自擁有一份父類對象的部分,而是共享一份父類對象的部分。聲明虛基類的時候加上virtual即可,並且在繼承這個虛基類的時候也要加上virtual關鍵字。



單繼承多層繼承和多繼承多層繼承的基類構造函數執行方式是不一樣的。

單繼承多層繼承,自頂向下如果有3層的話(A,B,C),那麼在創建C類對象的時候,只能在C類構造函數裏面的成員初始化列表裏面執行B類的構造函數,然後在B類構造函數的成員初始化列表裏面執行A類構造函數,也就是說只能夠執行相鄰的基類的構造函數。但是這一點在多繼承多層繼承的時候是有錯誤的。


多繼承多層繼承(A,BC,D)

因爲D繼承自BC兩個基類,在執行D的構造函數的時候,必然會在成員初始化列表中使用BC兩個構造函數,但是在BC兩個構造函數的執行的時候因爲同時都繼承了A,那麼在傳遞同一個參數都想執行A類的構造函數的時候將會沒有任何效果,A類將不會理會這兩個BC類傳進來的參數想執行構造函數的請求,直接執行默認的構造函數。爲了避免這種衝突的時候,如果A是虛基類的時候,禁止通過中間的基類傳遞給他參數執行他的構造函數,因爲在構造D類對象之前,或者說在構造任何子類對象之前都必須構造基類對象部分,所以可以在執行D類構造函數的時候,在成員初始化列表裏面執行A類的構造函數,並傳遞參數,否則A類將執行默認的構造函數。這種情況只對虛基類有用,如果用在非虛基類是違法耳朵。


類模板:

可以在對類模板實例化的時候傳遞多個參數,並且可以爲類型參數提供默認值。可以爲類模板的類型參數提供默認值,但是不能夠爲函數模板參數提供默認值。模板的具體化有幾種形式,我們一般用的都是默認的隱式實例化,也就是直接聲明一個對象然後指出所需要的類型,在不生成這個模板類的對象時,編譯器是不會將這個模板類實例化的。但是可以通過顯式調用,來使模板類實例化,也就是加上template class 模板名<類型>;這樣會在沒創建這個模板類實例化之後的類的對象時進行實例化模板類。類模板還有一種實例化的方式就是顯示具體實例化,他是爲了某一些特殊情況特殊要求而使用的,比如一些類需要的某一個成員方法可能比較特殊,那麼就是用這種形式來實例化模板類,這樣的話,以後再碰到這種需求也會繼續用這種特定的顯示具體化來實例化模板類,不會在使用通用的模式了。

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