#include using namespace std;
class a
};class b: public a
};class c: public b
};int main()
結果是:4,4,4 ;為什麼?
一,在private,protect,public的實際繼承中,派生類和基類擁有相同的虛函式表。
但如果是虛繼承,會怎麼樣?
class a;};
class b :virtual public a;};
class c : virtual public b;};
int main()
結果是:4,12,20 (僅在visual studio下編譯的結果,gcc的結果還是4,4,4)
二,虛繼承中
虛擬繼承是多重繼承中特有的概念。虛擬基類是為解決多重繼承而出現的。
類d繼承自類b1、b2,而類b1、b2都繼承自類a,因此出現如下圖所示的局面(非虛基類)。
為了節省記憶體空間,可以將b1、b2對a的繼承定義為虛擬繼承,而a就成了虛擬基類。
(1)visual studio編譯器
派生類與基類擁有自己的虛函式表,注意過載了基類的虛函式會產生覆蓋。
派生類還有乙個指向虛基類指標列表vbptr
(2)在gcc編譯下
派生類與基類還是共用同乙個虛函式表
派生類還有乙個指向虛基類指標列表vbptr,但是如果基類中沒有成員變數,那麼派生類就不儲存虛基類指標列表。
注意
:類中虛函式都共用同乙個虛函式表。過載基類的虛函式會產生覆蓋。
看以下題:
#include #include using namespace std;
class ca
virtual void b(){};
};//sizeof(ca)==8, f,b虛函式表共用,佔4,加上int 共8
class cb: virtual public ca //也有一種寫法是class cb : public virtual ca
};//sizeof(cb)==12 f過載了基類的,覆蓋了基類的虛函式表,所以是8+虛基類表4 =12
class cc: virtual public ca
};//sizeof(cc) 不共用虛函式表,自己虛函式表+自己虛基類表+基類的空間=16
class cd: public cb, public cc
;//sizeof(cd) = sizeof(ca)+sizeof(cb)-sizeof(a)=16+12-8=20 (因為a是共用的)
int main()
visual studio 結果:8,12,16,20
gcc結果:8,12,12,16 為什麼cc是12呢?因為虛函式表一直是共用的。
如果去掉ca中的成員變數:
visual studio結果:4,8,12,16
gcc結果:4,4,4,8 因為基類裡面沒有成員,所以派生類沒有所謂的虛基類指標列表,最後sizeof(cd)=sizeof(cc)+sizeof(cb);
虛函式,虛繼承
1 空類,空類單繼承,空類多繼承的sizeof include using namespace std class base1 class base2 class derived1 public base1 class derived2 public base1,public base2 int m...
虛繼承 虛函式
1.虛繼承簡單的說就是如果有兩個類都繼承了同乙個基類 a 那麼,如果有第三個類又繼承了這兩個類,第三個類就會出現有 兩個基類 a 的情況,虛繼承就能避免這種情況。從實現 來看 普通繼承 普通繼承 沒有使用虛基類 基類a class a class b public a class c public ...
虛繼承和虛函式繼承
虛繼承主要用於菱形 形式的繼承形式 虛繼承是為了在多繼承的時候避免引發歧義,比如類 有個就是a,繼承了 c也繼承了 當 多繼承 時,就會有歧義產生了,所以要使用虛擬繼承避免重複拷貝。虛函式繼承是解決多型性的,當用基類指標指向派生類物件的時候,基類指標呼叫虛函式的時候會自動呼叫派生類的虛函式,這就是多...