一:繼承和派生ios
0、默認構造函數即不帶參數的構造函數或者是系統自動生成的構造函數。每個類的構造函數能夠有多個,可是析構函數只能有一個。c++
一、採用公用public繼承方式,則基類的公有成員變量和成員函數的屬性繼承到派生類後不發生變化。例如book類的公有的setprice和settitle成員函數繼承到codingbook類後,這兩個成員變量的屬性仍將是public屬性。若是在繼承過程當中不指名繼承方式時,編譯器系統會默認繼承方式爲private或protected屬性。編程
二、派生類在繼承了父類的全部成員函數和成員變量後,是不能直接訪問基類的私有成員函數和成員變量的。函數
三、從基類派生出派生類,派生類繼承基類的繼承方式有三種:public、protected和private。在未指定的狀況下編譯器會默認繼承方式爲protected或private方式。
spa
四、使用using聲明能夠改變基類成員在派生類中的訪問屬性。咱們知道基類的公有成員通過公有繼承,在派生類中其屬性爲public的,可是經過using 聲明,咱們能夠將其改成private或protected屬性。設計
五、若是派生類中新增一個成員變量,該成員變量與基類中的成員變量同名,則新增的成員變量就會遮蔽從基類中繼承過來的成員變量。同理,若是派生類中新增的成員函數與基類中的成員函數同名,則該新增的成員函數就會遮蔽從基類中繼承過來的成員函數。指針
從上例中,咱們能夠看出被遮蔽了的基類的成員變量或成員函數並不是是沒有繼承過來,而僅僅是被派生類的同名成員變量和成員函數給遮蔽了,調用的時候須要用到類名加上域解析操做符。orm
六、假設類C繼承自類B,類B繼承自類A。那麼類C中的除了可以繼承B類的成員函數和成員變量外,一樣也能繼承B類繼承自A類的全部成員。換言之,類C能夠繼承來自類A的全部成員。所以繼承既能夠是直接繼承,也能夠是間接繼承。對象
七、繼承機制下的構造函數:派生類一樣有構造函數。當咱們建立一個派生類對象的時候,基類構造函數將會被自動調用,用於初始化派生類從基類中繼承過來的成員變量。而派生類中新增的成員變量則須要從新定義構造函數用於初始化了。不管是對象指針的方式或者是直接建立對象的方式都會先調用基類的構造函數,而後調用派生類的構造函數。blog
當咱們建立派生類對象時,先由派生類構造函數調用基類構造函數,而後再執行派生類構造函數函數體中的內容,也就是說先執行基類構造函數,而後再去執行派生類構造函數。若是繼承關係有好幾層的話,例如A類派生出B類,B類派生出C類,則建立C類對象時,構造函數的執行順序則爲A的構造函數,其次是B的構造函數,最後是C類的構造函數。構造函數的調用順序是按照繼承的層次,自頂向下,從基類再到派生類的。
八、派生類和基類構造函數的調用規則:基類默認構造函數-----》基類帶參構造函數-----》派生類默認構造函數-------》派生類帶參構造函數
九、派生類構造函數能夠自動調用基類的默認構造函數,可是前提是默認構造函數必須存在。一般狀況下,默認構造函數系統會自動生成的,可是若是在基類中,咱們本身定義了一個帶參數的構造函數,這個時候,系統是不會爲基類自動生成默認構造函數的,這個時候派生類則沒法自動調用基類的默認構造函數了,由於基類根本就不存在默認構造函數。遇到這種狀況有兩種解決方案:其一,在基類中定義一個默認構造函數(不帶參數的構造函數),例如上一節中的例2;其二,派生類中的每個構造函數都顯式的調用基類中的帶參構造函數,顯示調用方法:。
咱們還建議在設計類的時候爲每個類設計一個默認構造函數,畢竟默認構造函數並不會妨礙構造函數的顯式調用。一般咱們還會遇到這樣一種狀況,派生類中並未顯式定義構造函數,這個時候派生類中只有系統自動生成的默認構造函數,如此一來,若是咱們不爲基類設計一個默認構造函數,則程序就會編譯出錯。這種錯誤很玄妙,若是不當心還真是難以發現。爲了不這種狀況的發生,咱們建議爲每個類設計一個默認構造函數。
總的來講,在建立派生類對象時,必須顯式或隱式地調用基類的某一個構造函數,這一點很是重要。固然被調用的基類的構造函數能夠是帶參構造函數,也能夠是默認構造函數。
十、建立派生類對象時構造函數的調用順序是按照繼承順序,先執行基類構造函數,而後再執行派生類的構造函數。可是對於析構函數,其調用順序是正好相反的,即先執行派生類的構造函數,而後再執行基類的構造函數。構造函數的執行順序是按照繼承順序自頂向下的,從基類到派生類,而析構函數的執行順序是按照繼承順序自下向上,從派生類到基類。由於每個類中最多隻能有一個析構函數,所以調用的時候並不會出現二義性,所以析構函數不須要顯式的調用。
十一、c++多繼承:
在C++中一個派生類中容許有兩個及以上的基類,咱們稱這種狀況爲多繼承。單繼承中派生類是對基類的特例化,例如前面中編程類書籍是書籍中的特例。而多繼承中,派生類是全部基類的一種組合。在多繼承中,派生類繼承了全部基類中的全部成員變量和成員函數,這些繼承過來的成員變量及成員函數其訪問規則與單繼承是相同的。使用多繼承能夠描述事物之間的組合關係,可是如此一來也可能會增長命名衝突的可能性,衝突可能頗有可能發生在基類與基類之間,基類與派生類之間。命名衝突是必需要解決的問題。爲了解決命名衝突問題咱們只能採用域解析操做符來區分具體所調用的類中的成員函數,例如:。
十二、c++虛基類(虛繼承):
在多繼承時很容易產生命名衝突問題,若是咱們很當心地將全部類中的成員變量及成員函數都命名爲不一樣的名字時,命名衝突依然有可能發生,好比很是經典的菱形繼承層次。類A派生出類B和類C,類D繼承自類B和類C,這個時候類A中的成員變量和成員函數繼承到類D中變成了兩份,一份來自A派生B而後派生D這一路,另外一份來自A派生C而後派生D這一條路。
例1:
本例即爲典型的菱形繼承結構,類A中的成員變量及成員函數繼承到類D中均會產生兩份,這樣的命名衝突很是的棘手,經過域解析操做符已經沒法分清具體的變量了。爲此,C++提供了虛繼承這一方式解決命名衝突問題。虛繼承只須要在繼承屬性前加上virtual關鍵字。
例2:
在本例中,類B和類C都是繼承類A都是虛繼承,如此操做以後,類D只會獲得一份來自類A的數據。在本例的主函數中,定義了類D的對象test,而後經過該對象調用從類A間接繼承來的setx和getx成員函數,由於B和C繼承自類A採用的是虛繼承,故經過D調用setx和getx不會有命名衝突問題,由於D類只獲得了一份A的數據。