虛函式 虛繼承

2021-06-09 13:59:50 字數 1807 閱讀 3923

#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也繼承了 當 多繼承 時,就會有歧義產生了,所以要使用虛擬繼承避免重複拷貝。虛函式繼承是解決多型性的,當用基類指標指向派生類物件的時候,基類指標呼叫虛函式的時候會自動呼叫派生類的虛函式,這就是多...