1樓:
虛繼承是和多繼承相關的,你這裡沒有多繼承,virtual沒有意義!
除非b的派生類的派生類採用多繼承,並且繼承了兩個以上的b的派生類或子孫類,虛繼承沒有什麼用處;
虛繼承,是為了消除繼承體系中的的鑽石菱形,而定製的,沒有別的作用。
不管有沒有虛繼承,只要有虛擬函式,就會有虛擬函式表,就會在物件裡安排一個和虛擬函式表相關的vptr 這是c++物件導向特性的實現方法,具體安排和編譯器有關,也和繼承體系的複雜程度有關。
由於a類並無虛擬函式,虛繼承的必要性不大。虛繼承只和物件佈局相關,而物件佈局不同編譯器的實現是不同的。
a是個空類,本身並無虛擬函式,單獨定義一個物件,c++會為他分配至少一個位元組
繼承後由於b類有虛擬函式,指向虛擬函式表的vptr要佔一個指標長度的空間(你這裡4個位元組)
所以繼承a的b類不必再為基類a的物件再分配任何位元組了。
你這裡只有一個虛擬函式(無論多少虛擬函式,只有繼承體系比較複雜---具體就是指多繼承,才會有多個虛擬函式表,否則只有一個虛擬函式表,vptr自然只有一個了),
多繼承的基類物件安排比較複雜,基類物件,以及虛擬函式表可能不止一個,單一繼承,只會逐漸擴充套件繼承體系的結構,所有繼承層次物件的都是一個物件佈局逐層擴充套件而已,虛擬函式表都是派生類的虛擬函式表,只是逐漸擴大而已,vptr只需一個就夠了
所以b物件只有一個vptr而已4位元組足夠了,單獨定義的a物件需要1個或4個位元組;
b物件裡面的a物件不需要任何位元組(空類)
b物件無資料成員,只需要一個指標就夠了,所以是4個位元組
class a;
class ab:virtual public a;
class ac:virtual public a;
class b:public ab,public ac
;這裡 b物件只繼承一個a物件;所有a類的成員(成員函式和成員變數),都可以直接使用,不會造成二義性。
2樓:匿名使用者
你好,我用我的visual studio2014跑了一下你的**,註釋掉是4,不註釋是8,可見是編譯器不同,導致結果也不同,我的這個結果非常好解釋,virtual指標和虛擬函式指標所以是8
3樓:匿名使用者
跟編譯器的優化實現有關吧,往a加個函式可能結果又不一樣,實在不必過於糾結這個,虛繼承並不多用。
4樓:匿名使用者
virtual public a
你已經宣告瞭虛繼承了
c++中虛繼承與普通繼承的sizeof問題,求大神解
5樓:匿名使用者
對於class a,
(1)由於含有虛擬函式,包含虛擬函式指標,大小4位元組。
(2)a陣列的型別是char,大小是3,佔3位元組,因為需要前面對齊到4的整數倍,所以有1個佔位符。
因此,總的大小是4+3+1=8
對於class b,
(1)由於含有虛擬函式,包含虛擬函式指標,大小4位元組。
(2)b陣列型別是char,大小是3,佔3位元組。因為需要前面對齊到4的整數倍,所以有1個佔位符。
(3)繼承a的char陣列,大小是3,佔3位元組。因為需要前面對齊到4的整數倍,所以有1個佔位符。
因此,總的大小是4+3+1+3+1=12
對於class c,
(1)由於含有虛擬函式,包含虛擬函式指標,大小4位元組。
(2)c陣列型別是char,大小是3,佔3位元組。因為需要前面對齊到4的整數倍,所以有1個佔位符。
(3)由於是虛繼承,有一個指向父類的指標,大小位元組。
(4)父類a本身大小為8位元組。
因此,總的大小為4+3+1+4+8=20
c++虛擬函式,虛繼承的問題
6樓:匿名使用者
感覺你這寫的好複雜。。。一般的菱形繼承最多也就這樣:
class d :public /*virtual*/ b, public /*virtual*/ c
};而你這個,,是不是叫,,多虛繼承?
我這邊效果如下:(vs2013,64位,指標都是8個位元組)變化是 56,48,40,32,24。。
7樓:篤俠
可能是不同編譯器有不同的處理方式吧,在vc 6中 ...再去除virtual b中的virtual
結果就是16。
c++普通繼承和虛繼承
8樓:幻夢·人生
首先bai,class a包含一個虛擬函式,所du
以sizeof(a)的結果是zhi sizeof(虛表)的大小,也就是
dao4位元組回。
class b繼承class a,所以class b一定答是包含class a,只是包含的方式不同。
普通繼承,class a的虛表會和class b的虛表合併,所以class b中還是保留一個虛表就可以了。此時sizeof(b)的結果就是4.
虛繼承,class a和class b的關係就會微妙很多。由於c++支援多繼承,所以某些情況下會出現下圖中的繼承關係。這種水晶繼承會導致class d中包含兩份class a的物件。
此時就會出現訪問歧義的情況。
虛繼承就可以避免上面的情況。class a的資料會被放到虛表中。class d會識別到來自class b和c的虛表,然後將兩者合併。
所以回到本件問題,問題中的class b就會包含一份虛擬函式表指標,一份虛類指標。也就是sizeof(b)的結果是8。
能不能解釋一下c++中虛繼承的工作原理
9樓:v18867942223信
首先,class a包含一個虛擬函式,所以sizeof(a)的結果是 sizeof(虛表)的大小,也就是4位元組。
class b繼承class a,所以class b一定是包含class a,只是包含的方式不同。
普通繼承,class a的虛表會和class b的虛表合併,所以class b中還是保留一個虛表就可以了。此時sizeof(b)的結果就是4.
虛繼承,class a和class b的關係就會微妙很多。由於c++支援多繼承,所以某些情況下會出現下圖中的繼承關係。這種水晶繼承會導致class d中包含兩份class a的物件。
此時就會出現訪問歧義的情況。
虛繼承就可以避免上面的情況。class a的資料會被放到虛表中。class d會識別到來自class b和c的虛表,然後將兩者合併。
所以回到本件問題,問題中的class b就會包含一份虛擬函式表指標,一份虛類指標。也就是sizeof(b)的結果是8。
虛擬函式和純虛擬函式的兩個基礎小問題
純虛擬函式就是 強636f707962616964757a686964616f31333262373361制 要求在派生出具體類的時候 必須定義出的函式,否則該派生類就無法定義具體物件 而虛擬函式則可重新定義也可以不重新定義 說得對。而僅僅站在使用的角度去說,虛擬函式和純虛擬函式都可以實現多型的功能...
虛擬函式!!謝謝
這個程式之所以會報錯,是因為在類graduate裡面出現了歧義 你重新定義了函式display,雖然這個函式在基類是虛擬函式,但是在此類中你改變了它的返回值,使得這個定義變成了一個新的函式的定義,但是類graduate又繼承了基類的display函式,這兩個函式不能形成過載,所以在這裡display...
C 的虛擬函式有什麼用呢,C 中虛擬函式的作用是什麼?它應該怎麼用呢?
主要用在繼承抄與多型上 比如有一個襲汽車類,它有bai一個虛du函式alarm 就是鳴笛的聲zhi 音。汽車類有很多子 dao類,比如卡車類,小轎車類,他們的鳴笛聲音都一樣,所以只需繼承汽車類,不用在每個類裡重寫這個函式。現在如果新增一個卡丁車類,它的鳴笛聲音和其他類都不一樣,那就可以在這個類裡重寫...