虛函數的結束結點,標誌了虛函數表的結束。函數
在WinXP+VS2003下,這個值是NULL。佈局
而在Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3下,這個值是若是1,表示還有下一個虛函數表,若是值是0,表示是最後一個虛函數表。spa
1)虛函數按照其聲明順序放於表中。.net
2)父類的虛函數在子類的虛函數前面。3d
1)覆蓋的f()函數被放到了虛表中原來父類虛函數的位置。指針
2)沒有被覆蓋的函數依舊。xml
複雜一些的狀況:blog
咱們能夠看到:繼承
咱們能夠看見,最頂端的父類B其成員變量存在於B1和B2中,並被D給繼承下去了。而在D中,其有B1和B2的實例,因而B的成員在D的實例中存在兩份,一份是B1繼承而來的,另外一份是B2繼承而來的。因此,若是咱們使用如下語句,則會產生二義性編譯錯誤:內存
D d;
d.ib = 0; //二義性錯誤
d.B1::ib = 1; //正確
d.B2::ib = 2; //正確
上述的「重複繼承」只須要把B1和B2繼承B的語法中加上virtual 關鍵,就成了虛擬繼承
把B這個超類放到了最後
咱們知道,子類沒有重載父類的虛函數是一件毫無心義的事情。由於多態也是要基於函數重載的。雖然在上面的圖中咱們能夠看到Base1的虛表中有Derive的虛函數,但咱們根本不可能使用下面的語句來調用子類的自有虛函數:
Base1 *b1 = new Derive();
b1->f1(); //編譯出錯
任何妄圖使用父類指針想調用子類中的未覆蓋父類的成員函數的行爲都會被編譯器視爲非法。
2、訪問non-public的虛函數
另外,若是父類的虛函數是private或是protected的,但這些非public的虛函數一樣會存在於虛函數表中,因此,咱們一樣可使用訪問虛函數表的方式來訪問這些non-public的虛函數,這是很容易作到的。
咱們能夠經過獲得虛函數指針和偏移的方式取得上述說的兩種狀況。
轉載:https://blog.csdn.net/haoel/article/details/3081385