1樓:匿名使用者
這的確涉及了記憶體對齊,還有虛繼承vbptr指標,但是太複雜了,樓主弄明白了告訴我一聲。
虛函式和虛繼承的大小問題_乙個簡單程式
2樓:匿名使用者
我用的vc6,結果分別是8,20,32.
a的大小為8的原因是位元組對齊,即虛函式表指標佔4位元組,k佔3位元組,然後編譯器補了1位元組,將類的大小湊成4的倍數,以方便32位系統訪問。
b,c的大小依次增加12位元組。是因為多了子類自身的非繼承虛函式表指標4位元組,繼承自父類的虛函式表指標4位元組,char陣列3位元組加上補齊的1位元組。
c++ sizeof 虛函式和 虛繼承
3樓:
虛繼承是和多繼承相關的,你這裡沒有多繼承,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類的成員(成員函式和成員變數),都可以直接使用,不會造成二義性。
4樓:匿名使用者
你好,我用我的visual studio2014跑了一下你的**,註釋掉是4,不註釋是8,可見是編譯器不同,導致結果也不同,我的這個結果非常好解釋,virtual指標和虛函式指標所以是8
5樓:匿名使用者
跟編譯器的優化實現有關吧,往a加個函式可能結果又不一樣,實在不必過於糾結這個,虛繼承並不多用。
6樓:匿名使用者
virtual public a
你已經宣告了虛繼承了。
64位linux環境下帶有虛函式的類的sizeof問題
7樓:擁雲莊主
64位系統下,指標佔用8個位元組,所以,最後輸出為16。
我在64位linux下的測試截圖:
8樓:網友
64位,莫非是8位元組對齊。高階a
c++中虛函式的作用是什麼?它應該怎麼用呢?
9樓:莫斯利安純牛奶
c++中虛函式的作用:
1、簡單地說,那些被virtual關鍵字修飾的成員函式,就是虛函式。
2、實現多型性,多型性是將介面與實現進行分離。
3、當基類指標指向乙個子類物件,通過這個指標呼叫子類和基類同名成員函式的時候,基類宣告為虛函式就會調子類的這個函式,不宣告就會呼叫基類的。
c++中虛函式的用法:
1、比如你有個遊戲,遊戲裡有個虛基類叫「怪物」,有純虛函式 「攻擊」。
2、派生出了三個子類「狼」「蜘蛛」「蟒蛇」,都實現了自己不同的「攻擊」函式,比如狼是咬人,蜘蛛是吐絲,蟒蛇把你纏起來。
擴充套件資料:
使用虛函式的注意事項:
1、包含虛函式的類指標列表會增大。
2、虛析構函式。
(1)析構函式的作用是在物件撤銷之前做必要的「清理現場」的工作。
(2)當派生類的物件從記憶體中撤銷的時候,會先先呼叫派生類的析構函式然後再呼叫基類的析構函式。
(3)當我們new乙個臨時物件時,若基類中包含析構函式,並且定義了乙個指向該基類的指標變數。
3、建構函式不能宣告為虛函式。
建構函式不能宣告為虛函式。如果宣告為虛函式,編譯器會自動報出。
4、不在析構或者構造過程中呼叫虛函式。
在析構函式或者是建構函式中,我們絕對不能呼叫虛函式。即使,我們在建構函式或者析構函式中呼叫虛函式,也不會下降至派生類中呼叫函式。
10樓:木子青耶
虛函式的作用:
允許在派生類中重新定義與基類同名的函式,並且可以通過基類指標或引用來訪問基類和派生類中的同名函式。
虛函式的使用方法是:
1.在基類用virtual宣告成員函式為虛函式可以在派生類中重新定義此函式,為它賦予新的功能,並能方便地被呼叫。
在類外定義虛函式時,不必再加virtual。
2.在派生類中重新定義此函式,要求函式名、函式型別、函式引數個數和型別全部與基類的虛函式相同,並根據派生類的需要重新定義函式體。
在派生類重新宣告該虛函式時,可以加virtual,也可以不加,但習慣上一般在每一層宣告該函式時都加virtual,使程式更加清晰。
3.如果在派生類中沒有對基類的虛函式重新定義,則派生類簡單地繼承其直接基類的虛函式。
4.定義乙個指向基類物件的指標變數,並使它指向同一類族中需要呼叫該函式的物件。
通過該指標變數呼叫此虛函式,此時呼叫的就是指標變數指向的物件的同名函式;
虛函式與指向基類物件的指標變數的配合使用,就能方便地呼叫同一類族中不同類的同名函式,只要先用基類指標指向即可。
11樓:匿名使用者
c++中虛函式的作用:
1、為了方便使用多型特性,我們常常需要在基類中定義虛函式。
2、在很多情況下,基類本身生成物件是不合情理的。例如,動物作為乙個基類可以派生出老虎、孔雀等子類,但動物本身生成物件明顯不合常理。
為了解決上述問題,引入了純虛函式的概念,將函式定義為純虛函式(方法:virtual returntype function()=0;),則編譯器要求在派生類中必須予以重寫以實現多型性。
同時含有純虛函式的類稱為抽象類,它不能生成物件。這樣就很好地解決了上述兩個問題。
c++中虛函式的用法:
比如你有個遊戲,遊戲裡有個虛基類叫「怪物」,有純虛函式 「攻擊」。然後派生出了三個子類「狼」「蜘蛛」「蟒蛇」,都實現了自己不同的「攻擊」函式,比如狼是咬人,蜘蛛是吐絲,蟒蛇把你纏起來。
然後出現好多怪物的時候就可以定義乙個 虛基類指標陣列,把各種怪物的指標給它,然後迭代迴圈的時候直接 monster[i]->attack() 攻擊玩家就行了,大概見下圖:
乙個類物件有乙個int和double變數,沒有虛函式表,為什麼用sizeof顯示16個位元組呢
12樓:匿名使用者
預設對於只有基本型別成員的情況。
首先乙個成員變數在結構體中的相對位置必須能被自身尺寸整除。
其次乙個結構體的整體尺寸必須能被裡面尺寸最大的成員尺寸整除。
所以如果是int, double的情況double因為要在能被8整除的位置上,所以就成了int,浪費的4位元組,double
如果是double,int 因為double的尺寸是8,整個結構體的尺寸必須能被8整除就成了double,int,浪費的4位元組。
第一條的原因是,基本型別在能被自己尺寸整除的位置上讀寫速度是最快的。
第二條的目的是在申請這個型別的陣列的時候,保證整個陣列裡的所有成員都是對齊的。
13樓:匿名使用者
和結構體位元組對齊原理是一樣的。
double佔八個位元組。
int佔四個位元組,你用的系統應該預設是按照長的對齊,int也就佔了八個位元組。
一共十六個位元組。
14樓:匿名使用者
看下預設的位元組對其方式是不是8位元組?可以強制1位元組對齊或者4位元組對齊。
15樓:精品建築電氣
當無法確定你的變數的位元組數是可以用sizeof來控制。
ò»¸öàà¶ôïó£¬óðò»¸öchar³éô±£¬char*³éô±£¬int³éô±,ὸö³éô±º¯êý£¬áííâò»¸öð麯êý£¬îêsizeof¶àéù£¿
虛函式有什麼特點,虛函式和抽象函式有什麼區別?
定義虛函式必須是基類的非靜態成員函式,其訪問許可權可以是protected或public,在基類的類定義中定義虛函式的一般形式 virtual 函式返回值型別 虛函式名 形參表 編輯本段作用 虛函式的作用是實現動態聯編,也就是在程式的執行階段動態地選擇合適的成員函式,在定義了虛函式後,可以在基類的派...
c 中虛函式和純虛函式的作用與區別
包含純虛函式的類不可以例項化。c 中 虛函式與純虛函式的區別是什麼?虛函式與純虛函式 在他們的子類中都可以被重寫。它們的區別是 1 純虛函式只有定義,沒有實現 而虛函式既有定義,也有實現的 純虛函式一般沒有 實現部分,如 virtual void print 0 而一般虛函式必須要有 的實現部分,否...
雲計算與虛擬化的關係是,雲計算和虛擬化有什麼關係?
兩者沒有特殊關係。虛擬化是指將物理的實體,通過軟體模式,形成若干虛擬存在的系統,其實真是運作還是在實體上,只是劃分了若干區域或者時域劃分。雲計算的基礎是虛擬化,但虛擬化只是雲計算的一部分,雲計算其實就是在虛擬化出若干資源池以後的應用,但虛擬化並不是只對應雲計算的。雲計算一般都通過虛擬化的技術實現。父...