2011-05-03 22 views
4


,比如我有兩個 「intefaces」 和class類型:C++中虛擬表的結構是什麼?

class IPlugin 
{ 
    public: 
    virtual void Load(void) = 0; 
    virtual void Free(void) = 0; 
}; 

class IFoo 
{ 
    public: 
    virtual void Foo(void) = 0; 
}; 


class Tester: public IPlugin, public IFoo 
{ 
    public: 
      Tester() {}; 
      ~Tester() {}; 

      virtual void Load() 
      { 
       // Some code here 
      } 

      virtual void Free() 
      { 
       // Some code here 
      } 

      virtual void Foo(void) 
      { 
       // Some code here 
      } 
}; 

實際上有Tester類型的實例是什麼結構vtab?而如何將dynamic_cast操作行爲(我的意思是dynamic_cast運營商將如何掃描vtab爲有效的引用類型皈依)表達:

Tester* t = new Tester(); 
IPlugin* plg = dynamic_cast<IPlugin*>(t); 
IFoo* f = dynamic_cast<IFoo*>(plg); 

提前感謝!

+1

看看這裏http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/ – DumbCoder 2011-05-03 11:01:15

+1

虛擬函數調用的實現並沒有在C++標準中定義。對於所有編譯器和編譯器版本,您都不會得到正確的答案。 – harper 2011-05-03 11:13:36

+0

@DumbCoder:感謝您的鏈接,但事實證明,我的問題沒有普遍的答案 – 2011-05-03 11:45:16

回答

16

C++中的虛擬表是一個實現細節。下圖顯示了一種可能的實施方式。類(A和B)的

Virtual table diagram

兩個實例存在。每個實例都有兩個vtbl指針,而vtbl包含指向實際代碼的指針。

在你的例子中沒有實例數據,但我爲了說明的目的假設每個類都包含一些實例數據。

當指向Tester的指針被轉換爲指向IFoo的指針時,指針將按照圖中所示進行調整。而不是指向實例數據的開始,它指向實例數據的IFoo部分。

整潔的事情是,使用IFoo指針的調用者對該類的IFoo部分的數據沒有任何瞭解。使用IPlugin指針的呼叫者也可以這樣說。該指針碰巧指向也由Tester指針指向的實例數據的開始,但只有使用Tester指針的調用者知道實例數據的整個佈局。使用dynamic_cast需要不在圖中的RTTI(運行時類型信息)。 vtbl將包含額外的類型信息,給定一個說IFoo指向Tester實例的指針允許代碼在運行時發現指針指向的實際對象類型並使用它來向下指針。

5

什麼結構vtab實際上有類型測試器的實例?

虛擬調度機制是實現定義的。 vtable和vptr不是C++標準所要求的,而且程序員甚至不需要用C++編程,因爲你不能訪問虛擬表(即使你的編譯器實現了這一點)。它由編譯器生成並添加到代碼中,就像它在將代碼轉換爲機器代碼之前爲代碼做了很多事情一樣。


Tester* t = new Tester(); 
IPlugin* plg = dynamic_cast<IPlugin*>(t); 
IFoo* f = dynamic_cast<IFoo*>(plg); 

這裏dynamic_cast不需要在第二行。以下就足夠了:

Tester* t = new Tester(); 
IPlugin* plg = t;     //upcast   - dynamic_cast not needed 
IFoo* f=dynamic_cast<IFoo*>(plg); //horizontal-cast - dynamic_cast needed 

dynamic_cast在upcast中是不需要的;它只需要在垂直和水平投下。

Tester* tester1 = dynamic_cast<Tester*>(plg); //downcast - dynamic_cast needed 
Tester* tester2 = dynamic_cast<Tester*>(f); //downcast - dynamic_cast needed 
+0

@Nawaz:記得一年前的虛擬機制實現細節Q? :) – 2011-05-03 11:15:57

+0

@Als:哪裏?哪個主題?我不記得:-s – Nawaz 2011-05-03 11:16:36

+0

@Nawaz:[Here](http://stackoverflow.com/questions/4352032/a-question-about-virtual-mechanism-in-c)檢查OP和第一個評論者: ) – 2011-05-03 11:23:14

3

虛擬機制(虛擬指針&虛擬表)不是由C++標準定義的。編譯器以自己選擇的方式實施該機制,這是被遺漏的。它是編譯器的實現細節。鑑於此,編譯器將如何實現虛擬機制的細節是從用戶中抽象出來的。重要的只是虛擬機制中預期的行爲。

你的情況:

Tester* t = new Tester(); 
IPlugin* plg = dynamic_cast<IPlugin*>(t); 
IFoo* f = dynamic_cast<IFoo*>(plg); 

plg & f因爲t是他們兩個都派生將指向各自類型的有效的對象。

Ofcourse這並不回答你問的具體問題,但只是想清楚作爲編譯器實現細節的虛擬機制的細節。

+0

謝謝!我真的認爲,標準中指定的vtab :) – 2011-05-03 11:38:15