2011-08-23 114 views

回答

9

從技術上講,這是一個實現細節。 C++標準沒有提到vtable或vptrs。

但通常,編譯器只會在成員函數以多義意義被調用時(即通過指針/參考基類)調用vtable/vptr機制。如果它在編譯時知道要做什麼,那麼就不需要間接方法。

3

僅適用於虛擬函數查找。非虛擬成員函數並不需要太多特殊 - 它只是一個正常函數,它將this作爲隱藏參數。

1

該標準並沒有規定如何實現繼承,所以一個vtable不一定存在。但據我所知,目前所有主要編譯器都只使用vtable來調用虛擬函數。

1

dynamic_cast也會使用vtable,我相信。

0

據我所知,只有當被調用的方法被指定爲虛擬時,vtable纔會被創建(並因此被使用)。如果它是虛擬的,那麼它將使用vtable,如果它不是虛擬的,那麼它將被靜態綁定。

這個確定是在編譯時完成的。

-1

和方法指針查找。至少有一個檢查指針是否指向虛擬成員函數。

+0

支票?何時執行檢查? –

+0

編譯器不知道什麼是虛擬的,哪些不是虛擬的? –

+0

當一個方法指針被調用時,最後一位被測試:如果它是1,它是一個指向虛方法的指針,否則它是一個指向成員函數的指針。你可以用objdump輕鬆地檢查。你也可以檢查成員函數指針的大小,它不僅是一個指針。實際上它是一個偏移+調用方法的vtable中的地址或索引。 – Thomas

0

這始終是實現相關的,但大多數編譯器將使用虛函數表時:被稱爲

  • virtual功能;
  • 當使用dynamic_cast地址的vtables被使用。實際的vtable沒有被使用,但它必須存在有一個地址。
  • virtual -y繼承的類正在接受。

virtual -y繼承類訪問包括虛擬和非虛擬方法調用,而且現場訪問,甚至指針鑄造

class foo{ 
public: 
    virtual void bar(){} 
}; 

class foo2: public virtual foo{ 
public: 
    virtual void bar2(){} 
}; 

int main(int argc, char *argv[]) 
{ 
    foo2* f2= new foo2(); 
    f2->bar(); 
    foo* f1 = f2; 
} 

foo* f1 = f2;線也將讀取虛函數表(雖然首先檢查會用於f2 == NULL,在這種情況下f1也將爲NULL)。

相關問題