91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

虛函數和虛擬繼承的內存分布

發布時間:2020-06-24 02:33:43 來源:網絡 閱讀:850 作者:sunshine225 欄目:編程語言

一.虛函數

(1)C++中的虛函數的主要作用:實現了多態的機制

(2)多態:用父類型的指針指向其子類的實例,然后通過父類的指針調用實際子類的成員函數。這種技術可以讓父類的指針有“多種形態”,這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的代碼來實現可變的算法。比如:模板技術,RTTI技術,虛函數技術,要么是試圖做到在編譯時決議,要么試圖做到運行時決議。

(3)多態要基于函數重載,所以如果子類沒有重載父類的虛函數那是一件毫無意義的事情。


二.虛函數表

1.虛函數表:虛函數表C++的編譯器應該是保證虛函數表的指針存在于對象實例中最前面的位置(這是為了保證取到虛函數表的有最高的性能——如果有多層繼承或是多重繼承的情況下)。 這意味著我們通過對象實例的地址得到這張虛函數表,然后就可以遍歷其中函數指針,并調用相應的函數。

如圖:

虛函數和虛擬繼承的內存分布

虛函數表的最后多加了一個結點,這是虛函數表的結束結點,就像字符串的結束符“/0”一樣,其標志了虛函數表的結束。這個結束標志的值在不同的編譯器下是不同的。在WinXP+VS2003下,這個值是NULL。而在Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3下,這個值是如果1,表示還有下一個虛函數表,如果值是0,表示是最后一個虛函數表。


2.虛函數在虛函數表中的存放原則

1)虛函數按照其聲明順序放于表中。

2)父類的虛函數在子類的虛函數前面          

3)覆蓋的f()函數被放到了虛表中原來父類虛函數的位置。

4)沒有被覆蓋的函數依舊。

虛函數和虛擬繼承的內存分布

3.多重繼承

1) 每個父類都有自己的虛表。

2) 子類的成員函數被放到了第一個父類的表中。(所謂的第一個父類是按照聲明順序來判斷的)     這樣做就是為了解決不同的父類類型的指針指向同一個子類實例,而能夠調用到實際的函數。

虛函數和虛擬繼承的內存分布

三.進階

(1)單一的一般繼承

1)虛函數表在最前面的位置。

2)成員變量根據其繼承和聲明順序依次放在后面。

3)在單一的繼承中,被重寫的虛函數在虛函數表中得到了更新。

虛函數和虛擬繼承的內存分布x

(2)多重繼承(只是比上面的多重繼承多了個成員變量)

1)每個父類都有自己的虛表。

2)子類的成員函數被放到了第一個父類的表中。

3)內存布局中,其父類布局依次按聲明順序排列。

4)每個父類的虛表中的f()函數都被重寫成了子類的f()。這樣做就是為了解決不同的父類類型的指針指向同一個子類實例,而能夠調用到實際的函數。

虛函數和虛擬繼承的內存分布

(3)重復繼承

虛函數和虛擬繼承的內存分布

最頂端的父類B其成員變量存在于B1和B2中,并被D給繼承下去了。而在D中,其有B1和B2的實例,于是B的成員在D的實例中存在兩份,一份是B1繼承而來的,另一份是B2繼承而來的。所以,如果我們使用以下語句,則會產生二義性編譯錯誤:

D d;
d.ib = 0; //二義性錯誤
d.B1::ib = 1; //正確
d.B2::ib = 2; //正確

注意,上面例程中的最后兩條語句存取的是兩個變量。雖然我們消除了二義性的編譯錯誤,但B類在D中還是有兩個實例,這種繼承造成了數據的重復,我們叫這種繼承為重復繼承。重復的基類數據成員可能并不是我們想要的。所以,C++引入了虛基類的概念。


(4)重復虛擬繼承-把上述的“重復繼承”的B1和B2繼承B的語法中加上virtual 關鍵,就成了虛擬繼承

虛函數和虛擬繼承的內存分布

四.利用虛函數表做的壞事兒

(1)任何試圖使用父類指針調用子類中的未覆蓋父類的成員函數的行為都會被編譯器視為非法,但我們可以通過指針的方式訪問虛函數表來達到違反C++語義的行為。

(2)如果父類的虛函數是private或是protected的,但這些非public的虛函數同樣會存在于虛函數表中,所以,我們同樣可以使用訪問虛函數表的方式來訪問這些non-public的虛函數。


<有個疑惑:為什么最后一個多重虛繼承B的地址在最后?請大家指教一下,我也下去再好好研究一下>

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淮滨县| 平度市| 寻乌县| 永川市| 萨嘎县| 秦安县| 康马县| 鄂尔多斯市| 台南县| 南充市| 屏边| 赣州市| 浪卡子县| 桓台县| 湘阴县| 新竹市| 开化县| 莲花县| 东兰县| 平乐县| 永善县| 牟定县| 革吉县| 安阳县| 龙口市| 日照市| 南安市| 苏尼特右旗| 牙克石市| 旌德县| 昌图县| 丰宁| 治县。| 新安县| 镇赉县| 兴城市| 扎囊县| 抚顺县| 金阳县| 元朗区| 正蓝旗|