多重继承、虚继承与虚基类
一、多重繼承
單重繼承——一個(gè)派生類(lèi)最多只能有一個(gè)基類(lèi)
多重繼承——一個(gè)派生類(lèi)可以有多個(gè)基類(lèi)
class 類(lèi)名: 繼承方式 基類(lèi)1,繼承方式 基類(lèi)2,…. {….};
派生類(lèi)同時(shí)繼承多個(gè)基類(lèi)的成員,更好的軟件重用
可能會(huì)有大量的二義性,多個(gè)基類(lèi)中可能包含同名變量或函數(shù)
多重繼承中解決訪問(wèn)歧義的方法:
基類(lèi)名::數(shù)據(jù)成員名(或成員函數(shù)(參數(shù)表))
明確指明要訪問(wèn)定義于哪個(gè)基類(lèi)中的成員
C++ Code?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | ? | #include?<iostream> using?namespace?std; class?Bed { public: ????Bed(int?weight)?:?weight_(weight) ????{ ????} ????void?Sleep() ????{ ????????cout?<<?"Sleep?..."?<<?endl; ????} ????int?weight_; }; class?Sofa { public: ????Sofa(int?weight)?:?weight_(weight) ????{ ????} ????void?WatchTV() ????{ ????????cout?<<?"Watch?TV?..."?<<?endl; ????} ????int?weight_; }; class?SofaBed?:?public?Bed,?public?Sofa { public: ????SofaBed()?:?Bed(0),?Sofa(0) ????{ ????????FoldIn(); ????} ????void?FoldOut() ????{ ????????cout?<<?"FoldOut?..."?<<?endl; ????} ????void?FoldIn() ????{ ????????cout?<<?"FoldIn?..."?<<?endl; ????} }; int?main(void) { ????SofaBed?sofaBed; ????//sofaBed.weight_?=?10;?error ????//sofaBed.weight_?=?20;?error ????sofaBed.Bed::weight_?=?10; ????sofaBed.Sofa::weight_?=?20; ????sofaBed.WatchTV(); ????sofaBed.FoldOut(); ????sofaBed.Sleep(); ????return?0; } |
不能直接寫(xiě)?sofaBed.weight_ = 10; 因?yàn)閟ofaBed 繼承了Sofa 和 Bed ,實(shí)際上有weigh_的兩份拷貝,這樣指向不明。只能通過(guò)
sofaBed.Bed::weight_ = 10; 訪問(wèn),但實(shí)際上一個(gè)sofaBed理應(yīng)只有一個(gè)weight_,下面通過(guò)虛基類(lèi)和虛繼承可以解決這個(gè)問(wèn)題。
二、虛繼承與虛基類(lèi)
當(dāng)派生類(lèi)從多個(gè)基類(lèi)派生,而這些基類(lèi)又從同一個(gè)基類(lèi)派生,則在訪問(wèn)此共同基類(lèi)中的成員時(shí),將產(chǎn)生二義性,可以采用虛基類(lèi)來(lái)解決。
虛基類(lèi)的引入
用于有共同基類(lèi)的場(chǎng)合
聲明
以virtual修飾說(shuō)明基類(lèi) 例:class B1:virtual public BB
作用
主要用來(lái)解決多繼承時(shí)可能發(fā)生的對(duì)同一基類(lèi)繼承多次而產(chǎn)生的二義性問(wèn)題.
為最遠(yuǎn)的派生類(lèi)提供唯一的基類(lèi)成員,而不重復(fù)產(chǎn)生多次拷貝
?
C++ Code?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | ? | #include?<iostream> using?namespace?std; class?Furniture { public: ????Furniture(int?weight)?:?weight_(weight) ????{ ????????cout?<<?"Furniture?..."?<<?endl; ????} ????~Furniture() ????{ ????????cout?<<?"~Furniture?..."?<<?endl; ????} ????int?weight_; }; class?Bed?:?virtual?public?Furniture { public: ????Bed(int?weight)?:?Furniture(weight) ????{ ????????cout?<<?"Bed?..."?<<?endl; ????} ????~Bed() ????{ ????????cout?<<?"~Bed?..."?<<?endl; ????} ????void?Sleep() ????{ ????????cout?<<?"Sleep?..."?<<?endl; ????} }; class?Sofa?:?virtual?public?Furniture { public: ????Sofa(int?weight)?:?Furniture(weight) ????{ ????????cout?<<?"Sofa?..."?<<?endl; ????} ????~Sofa() ????{ ????????cout?<<?"~Sofa?..."?<<?endl; ????} ????void?WatchTV() ????{ ????????cout?<<?"Watch?TV?..."?<<?endl; ????} }; class?SofaBed?:?public?Bed,?public?Sofa { public: ????SofaBed(int?weight)?:?Bed(weight),?Sofa(weight),?Furniture(weight) ????{ ????????cout?<<?"SofaBed?..."?<<?endl; ????????FoldIn(); ????} ????~SofaBed() ????{ ????????cout?<<?"~SofaBed?..."?<<?endl; ????} ????void?FoldOut() ????{ ????????cout?<<?"FoldOut?..."?<<?endl; ????} ????void?FoldIn() ????{ ????????cout?<<?"FoldIn?..."?<<?endl; ????} }; int?main(void) { ????SofaBed?sofaBed(5); ????sofaBed.weight_?=?10; ????sofaBed.WatchTV(); ????sofaBed.FoldOut(); ????sofaBed.Sleep(); ????return?0; } |
此時(shí)只有一份weigh_,不存在訪問(wèn)歧義的問(wèn)題。
從輸出可以總結(jié)出:
1、虛基類(lèi)的成員是由最遠(yuǎn)派生類(lèi)的構(gòu)造函數(shù)通過(guò)調(diào)用虛基類(lèi)的構(gòu)造函數(shù)進(jìn)行初始化的。
2、在整個(gè)繼承結(jié)構(gòu)中,直接或間接繼承虛基類(lèi)的所有派生類(lèi),都必須在構(gòu)造函數(shù)的成員初始化表中給出對(duì)虛基類(lèi)的構(gòu)造函數(shù)的調(diào)用。如果未列出,則表示調(diào)用該虛基類(lèi)的默認(rèn)構(gòu)造函數(shù)。
3、在建立對(duì)象時(shí),只有最遠(yuǎn)派生類(lèi)的構(gòu)造函數(shù)調(diào)用虛基類(lèi)的構(gòu)造函數(shù),該派生類(lèi)的其他基類(lèi)對(duì)虛基類(lèi)構(gòu)造函數(shù)的調(diào)用被忽略。
?
參考:
C++ primer 第四版
Effective C++ 3rd
C++編程規(guī)范
總結(jié)
以上是生活随笔為你收集整理的多重继承、虚继承与虚基类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: springboot与thymeleaf
- 下一篇: 《数据科学家访谈录》读书笔记