📑 Table of Contents

程序设计中的虛擬方法表(virtual method table)、虛擬函式表(virtual function table)或vtable,是一種编程语言裡支持动态分派(在運行時英语Run time (program lifecycle phase)進行方式绑定)的方式。

若有類別定義了虚函数(或虛方法),大部份的編譯器會在此類中加入隱藏成员变量,此变量是一個指向函式陣列(即為虛擬方法表)指標。在程式運行時會使用此指標,呼叫適當的函式實現,在編譯時,還不知道要呼叫哪一個函式,或是要呼叫某個繼承此類別的類別所實現的函式。

要實現动态分派的方式有很多種,但在C++以及其他相關語言(如D語言C#)裡常會使用虛擬方法表。一些將物件的程式介面和其實現分開的語言,像是Visual BasicDelphi,也常使用此一作法,因為此作法可以讓物件用設定另一個方法指標的方式,就可以使用不同的函式實現。此作法可以創建外部的函式庫,其他類似的技術則不行[1]

假設程式中包括三個有繼承關係的類別:母類別Cat,以及二個子類別HouseCatLionCat類別定義了虚函数,名稱為speak,其子類別可以提供適當的實現(例如meowroar)。當程式呼叫Cat參考(指向CatHouseCatLion的個體),程式必須要可以確認要呼叫哪一函式。這會依物件實際的類別而定,不是參考本身的類別。此類別無法在編譯期就決定要呼叫哪一個函式,需要在運行時才動態決定要呼叫哪一個函式。

實現

编辑

物件的虛擬方法表會包括物件動態綁定方法的記憶體位址。會透過物件的虛擬方法表,從其中方法的位址來呼叫方法。屬於同一個類別的物件會有相同的虛擬方法表,因此這些物件可以共用虛擬方法表。屬於相容類別的物件(例如繼承自同一個類別的各類別下的物件)會有相同佈置的虛擬方法表:在所有相容類別內,特定方法會在虛擬方法表中相同的位置。因此透過虛擬方法表讀取方法位置,就可以找到此物件方法的位置,以此呼叫函式[2]

C++標準沒有強制指定動態分配實現的作法,不過各編譯器都是依照相同的基本模式,只有小部份的差異。

一般來說,編譯器會為每一個有虛擬方法的類別分別創建虛擬方法表。當產生一個物件時,這個物件會多一個隱藏成員,此成員是指向虛擬方法表的指標,也稱為虛擬方法表指標vpointerVPTR。因此,編譯器也需要在物件的构造器中增加隱藏程式碼,讓新物件的虛擬方法表指標指向其虛擬方法表。

許多編譯器會將虛擬方法表當作物件裡的最後一名成員,也有編譯器將虛擬方法表當作第一個成員。這兩種方式都可以產生可移殖的程式碼[3]g++以往就將指標當成物件的最後一名成員[4]

相關條目

编辑

參考資料

编辑
  • Margaret A. Ellis and Bjarne Stroustrup (1990) The Annotated C++ Reference Manual. Reading, MA: Addison-Wesley. (ISBN 0-201-51459-1)
  1. ^ Zendra, Olivier; Colnet, Dominique; Collin, Suzanne. Efficient Dynamic Dispatch without Virtual Function Tables: The SmallEiffel Compiler -- 12th Annual ACM SIGPLAN Conference on Object-Oriented Programming Systems, Languages and Applications (OOPSLA'97), ACM SIGPLAN, Oct 1997, Atlanta, United States. pp.125-141. inria-00565627. Centre de Recherche en Informatique de Nancy Campus Scientifique, Bâtiment LORIA. 1997: 16 [2025-02-03]. (原始内容存档于2021-12-07). 
  2. ^ Ellis & Stroustrup 1990, pp. 227–232
  3. ^ Danny Kalev. "C++ Reference Guide: The Object Model II"页面存档备份,存于互联网档案馆). 2003. Heading "Inheritance and Polymorphism" and "Multiple Inheritance".
  4. ^ C++ ABI Closed Issues. [2011-06-17]. (原始内容存档于25 July 2011). 

📚 Artikel Terkait di Wikipedia

C++/CX

Foo^ foo = ref new Foo(); 一个WinRT变量仅仅是一对指针,一个指向虚函数表(Virtual method table(页面存档备份,存于互联网档案馆)),另一个指向物件的内部数据(Opaque pointer(页面存档备份,存于互联网档案馆))。

模板元編程

polymorphic)行為是藉由擁有虛擬函式的類別所產生的虛擬函式表(virtual look-up tables(英语:Virtual method table))來實行的。虛擬函式表會在執行期被查找,以決定該喚起哪個函式。因此動態多型無可避免地必須承擔這些執行期成本。

指標 (電腦科學)

資料庫(DLL)的進入點位址。在物件導向程式設計中,使用函數指標(Function pointer)來綁定方法(method),常見於虛擬方法表(Virtual method table)中。 但是指標本身也存在一些可被濫用之处,在存取某個資料結構時,可能會超出可用範圍,使軟體或作業系統出現異常,

算法效率

of algorithms 推测执行 求值策略 分支預測器 Super-threading 超執行緒 Threaded code Virtual method table Green, Christopher, Classics in the History of Psychology, [19 May

组件对象模型

生命期管理与类型转换,以访问不同的预定义接口。 IUnknown接口以及基于IUnknown的定制接口包括一个指向虚函数表(英语:virtual method table)的指针,虚函数表中包含若干函数指针,分别指向接口所声明的函数实现。对于进程内的COM组件调用,其效率等同于C++的虚函数调用。

ASP.NET MVC Framework

Web.Mvc.Html命名空間的方法,以延伸方法(Extension Method)的方式,讓產生HTML的程式就有如呼叫方法般簡單: <h2>Index</h2> <table> <tr> <th></th> <th> Id </th> <th> Name </th> </tr>

Python

with "function or method", and you get a pretty accurate description of Python's object model.  Simionato, Michele. The Python 2.3 Method Resolution Order

南非

[2013年8月24日]. ISBN 978-0-17-444706-1. (原始内容存档于2013年10月11日).  GNI per capita, Atlas method (current US$). The World Bank. [2019-10-30]. (原始内容存档于2018-09-30).  「方言」之謎:南非語是怎樣成為官方語言的?