友元關係不能繼承,因為友元不是類的成員,也就是說基類友元不能訪問子類私有和保護成員。
基類定義了static靜態成員,則整個繼承體系裡面只有乙個這樣的成員。無論派生出多少個子類,都只有乙個static成員例項。單繼承中子類只有乙個基類。單繼承子類物件模型:
多繼承中子類至少有兩個基類。
classb1;
classb2;
classd:
public b2,
public b1
;int
main()
多繼承子類物件模型:
注意:如果是多繼承,基類中成員在子類中的排列次序與繼承列表中基類的先後次序一致。例如上述的b1,b2。
class
bint _b;};
// 單繼承
classc1:
public b
;// 單繼承
classc2:
public b
;// 多繼承
classd:
public c1,
public c2
;
繼承模型圖:
上圖中c1繼承b,c2也繼承b,這兩種繼承方式都是單繼承。d繼承c1,c2,d為多繼承。整體的繼承方式為菱形繼承。派生類d中包含有兩個_b,乙個是c1繼承基類的,另乙個是c2繼承基類。
菱形繼承存在二義性問題:如果使用者在派生類中需要改變_b 的值(d._b = 1),編譯器就不知道從哪個基類中繼承下來的值,因此產生了二義性。
二義性的解決辦法:
讓訪問明確化–>對於存在二義性的成員在訪問時加基類名稱::
例如,d.c1::_b = 2; d.c2::f();該種解決方式可以讓**通過編譯,但是最頂層基類中的成員在底層派生類仍然儲存了兩份。
本質上解決是讓最頂層基類中成員在最底層中只儲存了乙份—>虛擬繼承。
虛擬繼承:在繼承許可權前面加上virtual關鍵字。
物件模型:
重要解釋:
虛擬繼承唯一的作用就是在菱形繼承中,解決菱形繼承中二義性的問題。
菱形虛擬繼承:
菱形虛擬繼承各類分布如上圖所示,按照繼承的先後順序,c1類在最上面,下來是c2類,然後是子類新增的成員變數,最後是基類的成員變數。在c1類中虛基表指標0代表相對於自己的偏移量,20位元組代表基類成員變數相對於c1類的偏移量,同理c2。注意:虛基表儲存在常量區,不能被修改。
c1& c1 = d;
c1._c1 =1;
//直接訪問
c1._b =2;
//通過虛基表的偏移量訪問
c2& c2 = d;
c2._c2 =1;
//直接訪問
c2._b =2;
//通過虛基表的偏移量訪問
C 下的多繼承
下面是 的一篇關於c 下多繼承的實現及其原理。include class a virtual void show virtual void dispa class b virtual void show virtual void dispb class c virtual void show vir...
C 中的繼承
一 繼承 什麼是繼承 繼承是允許重用現有類去建立新類的過程。分類的原則是乙個類派生出來的子類具有這個類的所有非私有的屬性。1 繼承c 中的類 c 不支援多重繼承,c 類始終繼承自乙個基類 如果未在宣告中指定乙個基類,則繼承自 system.object 派生類繼承基類的語法如下 using syst...
C 中的繼承
繼承,資料抽象和動態繫結是物件導向程式設計的核心思想。使用繼承,可以定義相似的型別並對其相似關係進行建模。通過繼承聯絡在一起的類構成一種層次關係,通常在層次關係的根部有乙個基類,其他類則直接或間接地從基類繼承而來,這些繼承得到的類稱為派生類。下面就讓我們一起來 繼承中的一些常見問題。1.繼承方式cl...