Virtual method table

In computer programming, a virtual method table (VMT), virtual function table, virtual call table, dispatch table, vtable, or vftable is a mechanism used in a programming language to support dynamic dispatch (or run-time method binding).

Whenever a class defines a virtual function (or method), most compilers add a hidden member variable to the class that points to an array of pointers to (virtual) functions called the virtual method table. These pointers are used at runtime to invoke the appropriate function implementations, because at compile time it may not yet be known if the base function is to be called or a derived one implemented by a class that inherits from the base class.

There are many different ways to implement such dynamic dispatch, but use of virtual method tables is especially common among C++ and related languages (such as D and C#). Languages that separate the programmatic interface of objects from the implementation, like Visual Basic and Delphi, also tend to use this approach, because it allows objects to use a different implementation simply by using a different set of method pointers. The method allows creation of external libraries, where other techniques perhaps may not.[1]

Suppose a program contains three classes in an inheritance hierarchy: a superclass, Cat, and two subclasses, HouseCat and Lion. Class Cat defines a virtual function named speak, so its subclasses may provide an appropriate implementation (e.g. either meow or roar). When the program calls the speak function on a Cat reference (which can refer to an instance of Cat, or an instance of HouseCat or Lion), the code must be able to determine which implementation of the function the call should be dispatched to. This depends on the actual class of the object, not the class of the reference to it (Cat). The class cannot generally be determined statically (that is, at compile time), so neither can the compiler decide which function to call at that time. The call must be dispatched to the right function dynamically (that is, at run time) instead.

Implementation

An object's virtual method table will contain the addresses of the object's dynamically bound methods. Method calls are performed by fetching the method's address from the object's virtual method table. The virtual method table is the same for all objects belonging to the same class, and is therefore typically shared between them. Objects belonging to type-compatible classes (for example siblings in an inheritance hierarchy) will have virtual method tables with the same layout: the address of a given method will appear at the same offset for all type-compatible classes. Thus, fetching the method's address from a given offset into a virtual method table will get the method corresponding to the object's actual class.[2]

The C++ standards do not mandate exactly how dynamic dispatch must be implemented, but compilers generally use minor variations on the same basic model.

Typically, the compiler creates a separate virtual method table for each class. When an object is created, a pointer to this table, called the virtual table pointer, vpointer or VPTR, is added as a hidden member of this object. As such, the compiler must also generate "hidden" code in the constructors of each class to initialize a new object's virtual table pointer to the address of its class's virtual method table.

Many compilers place the virtual table pointer as the last member of the object; other compilers place it as the first; portable source code works either way.[3] For example, g++ previously placed the pointer at the end of the object.[4]

Example

Consider the following class declarations in C++ syntax:

class B1 {
public:
  virtual ~B1() {}
  void fnonvirtual() {}
  virtual void f1() {}
  int int_in_b1;
};

class B2 {
public:
  virtual ~B2() {}
  virtual void f2() {}
  int int_in_b2;
};

used to derive the following class:

class D : public B1, public B2 {
public:
  void d() {}
  void f2() override {}
  int int_in_d;
};

and the following piece of C++ code:

B2 *b2 = new B2();
D  *d  = new D();

g++ 3.4.6 from GCC produces the following 32-bit memory layout for the object b2:[nb 1]

b2:
  +0: pointer to virtual method table of B2
  +4: value of int_in_b2

virtual method table of B2:
  +0: B2::f2()   

and the following memory layout for the object d:

d:
  +0: pointer to virtual method table of D (for B1)
  +4: value of int_in_b1
  +8: pointer to virtual method table of D (for B2)
 +12: value of int_in_b2
 +16: value of int_in_d

Total size: 20 Bytes.

virtual method table of D (for B1):
  +0: B1::f1()  // B1::f1() is not overridden

virtual method table of D (for B2):
  +0: D::f2()   // B2::f2() is overridden by D::f2()
                // The location of B2::f2 is not in the virtual method table for D

Note that those functions not carrying the keyword virtual in their declaration (such as fnonvirtual() and d()) do not generally appear in the virtual method table. There are exceptions for special cases as posed by the default constructor.

Also note the virtual destructors in the base classes, B1 and B2. They are necessary to ensure delete d can free up memory not just for D, but also for B1 and B2, if d is a pointer or reference to the types B1 or B2. They were excluded from the memory layouts to keep the example simple. [nb 2]

Overriding of the method f2() in class D is implemented by duplicating the virtual method table of B2 and replacing the pointer to B2::f2() with a pointer to D::f2().

Multiple inheritance and thunks

The g++ compiler implements the multiple inheritance of the classes B1 and B2 in class D using two virtual method tables, one for each base class. (There are other ways to implement multiple inheritance, but this is the most common.) This leads to the necessity for "pointer fixups", also called thunks, when casting.

Consider the following C++ code:

D  *d  = new D();
B1 *b1 = d;
B2 *b2 = d;

While d and b1 will point to the same memory location after execution of this code, b2 will point to the location d+8 (eight bytes beyond the memory location of d). Thus, b2 points to the region within d that "looks like" an instance of B2, i.e., has the same memory layout as an instance of B2.[clarification needed]

Invocation

A call to d->f1() is handled by dereferencing d's D::B1 vpointer, looking up the f1 entry in the virtual method table, and then dereferencing that pointer to call the code.

Single inheritance

In the case of single inheritance (or in a language with only single inheritance), if the vpointer is always the first element in d (as it is with many compilers), this reduces to the following pseudo-C++:

(*((*d)[0]))(d)

Where *d refers to the virtual method table of D and [0] refers to the first method in the virtual method table. The parameter d becomes the "this" pointer to the object.

Multiple inheritance

In the more general case, calling B1::f1() or D::f2() is more complicated:

(*(*(d[0]/*pointer to virtual method table of D (for B1)*/)[0]))(d)   /* Call d->f1() */
(*(*(d[8]/*pointer to virtual method table of D (for B2)*/)[0]))(d+8) /* Call d->f2() */

The call to d->f1() passes a B1 pointer as a parameter. The call to d->f2() passes a B2 pointer as a parameter. This second call requires a fixup to produce the correct pointer. The location of B2::f2 is not in the virtual method table for D.

By comparison, a call to d->fnonvirtual() is much simpler:

(*B1::fnonvirtual)(d)

Efficiency

A virtual call requires at least an extra indexed dereference and sometimes a "fixup" addition, compared to a non-virtual call, which is simply a jump to a compiled-in pointer. Therefore, calling virtual functions is inherently slower than calling non-virtual functions. An experiment done in 1996 indicates that approximately 6–13% of execution time is spent simply dispatching to the correct function, though the overhead can be as high as 50%.[5] The cost of virtual functions may not be so high on modern CPU architectures due to much larger caches and better branch prediction.

Furthermore, in environments where JIT compilation is not in use, virtual function calls usually cannot be inlined. In certain cases it may be possible for the compiler to perform a process known as devirtualization in which, for instance, the lookup and indirect call are replaced with a conditional execution of each inlined body, but such optimizations are not common.

To avoid this overhead, compilers usually avoid using virtual method tables whenever the call can be resolved at compile time.

Thus, the call to f1 above may not require a table lookup because the compiler may be able to tell that d can only hold a D at this point, and D does not override f1. Or the compiler (or optimizer) may be able to detect that there are no subclasses of B1 anywhere in the program that override f1. The call to B1::f1 or B2::f2 will probably not require a table lookup because the implementation is specified explicitly (although it does still require the 'this'-pointer fixup).

Comparison with alternatives

The virtual method table is generally a good performance trade-off to achieve dynamic dispatch, but there are alternatives, such as binary tree dispatch, with higher performance in some typical cases, but different trade-offs.[1][6]

However, virtual method tables only allow for single dispatch on the special "this" parameter, in contrast to multiple dispatch (as in CLOS, Dylan, or Julia), where the types of all parameters can be taken into account in dispatching.

Virtual method tables also only work if dispatching is constrained to a known set of methods, so they can be placed in a simple array built at compile time, in contrast to duck typing languages (such as Smalltalk, Python or JavaScript).

Languages that provide either or both of these features often dispatch by looking up a string in a hash table, or some other equivalent method. There are a variety of techniques to make this faster (e.g., interning/tokenizing method names, caching lookups, just-in-time compilation).

See also

Notes

  1. ^ G++'s -fdump-class-hierarchy (starting with version 8: -fdump-lang-class) argument can be used to dump virtual method tables for manual inspection. For AIX VisualAge XlC compiler, use -qdump_class_hierarchy to dump class hierarchy and virtual function table layout.
  2. ^ "C++ - why there are two virtual destructor in the virtual table and where is address of the non-virtual function (gcc4.6.3)".

References

  1. ^ a b Zendra, Olivier; Colnet, Dominique; Collin, Suzanne (1997). 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. p. 16.
  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". Archived from the original on 25 July 2011. Retrieved 17 June 2011.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  5. ^ Driesen, Karel and Hölzle, Urs, "The Direct Cost of Virtual Function Calls in C++", OOPSLA 1996
  6. ^ Zendra, Olivier and Driesen, Karel, "Stress-testing Control Structures for Dynamic Dispatch in Java", pp. 105–118, Proceedings of the USENIX 2nd Java Virtual Machine Research and Technology Symposium, 2002 (JVM '02)

Read other articles:

غلاف لكتاب كتب عليه الشعر الشعر العربي في العصر الأموي يعد العصر الأموي واحدًا من أكثر عصور الأدب ازدهارًا في نتاجِه الشعري، فقد بلغ الأدب العربي أوجها في هذا العصر، واحتضنته بيئات جديدة غير بيئة الجزيرة العربية، مما جعل هذا الأدب يتلون بألوان هذه البيئات ويتأثر بها، فقد ...

 

 

2,000 lb (910 kg) unpowered guided weapon GBU-10 Paveway II Type2,000 lb (910 kg) unpowered guided weaponSpecificationsLength14 ft 4 in (4.37 m)Diameter18 in (460 mm)Effective firing rangeMore than 8 nmi (9.2 mi; 15 km) The GBU-10 Paveway II is an American Paveway-series laser-guided bomb, based on the Mk 84 general-purpose bomb, but with laser seeker and wings for guidance. Introduced into service c. 1976. Used by USAF, US...

 

 

Aerial photo of the South Saskatchewan River, c. 1940s. The city of Saskatoon developed around the South Saskatchewan River. The history of Saskatoon began with the first permanent non-indigenous settlement of Saskatoon, Saskatchewan, Canada, in 1883 when Toronto Methodists, wanting to escape the liquor trade in that city, decided to set up a dry community in the rapidly growing prairie region. As of 1882 this area was a part of the provisional district named Saskatchewan, North-West Te...

Cet article est une ébauche concernant une commune de la Loire. Vous pouvez partager vos connaissances en l’améliorant (comment ?). Le bandeau {{ébauche}} peut être enlevé et l’article évalué comme étant au stade « Bon début » quand il comporte assez de renseignements encyclopédiques concernant la commune. Si vous avez un doute, l’atelier de lecture du projet Communes de France est à votre disposition pour vous aider. Consultez également la page d’aide à ...

 

 

1960 film This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Culpable film – news · newspapers · books · scholar · JSTOR (March 2019) (Learn how and when to remove this template message) CulpableDirected byHugo del CarrilWritten byEduardo BorrásProduced byHugo del CarrilCinematographyAmérico HossEdited b...

 

 

Philip Schuyler Información personalNacimiento 20 de noviembre de 1733 Albany (Estados Unidos) Fallecimiento 18 de noviembre de 1804 (70 años)Albany (Estados Unidos) Sepultura Albany Rural Cemetery Nacionalidad Británica y estadounidenseReligión Iglesia reformada neerlandesa FamiliaPadres Johannes Schuyler, Jr. Cornelia Stephanuse Schuyler Cónyuge Catherine Van Rensselaer Hijos Elizabeth Schuyler HamiltonAngelica Church Información profesionalOcupación Político y oficial militar Cargo...

Homeotic protein bicoidIdentifiersOrganismeDrosophila melanogasterSimbolbcdUniProtP09081PencarianStrukturSwiss-modelDomainInterPro (Atas) Gradien protein Bicoid Nuklir dalam embrio Drosophila transgenik tetap yang membawa gen fusi Bicoid-GFP. Gambar milik Julien O. Dubuis dan Thomas Gregor. (Bawah) Protein bicoid-GFP (hijau) dan mRNA bicoid berlabel IKAN (merah) di ujung anterior embrio Drosophila transgenik tetap. Kedua embrio berorientasi dengan kutub anterior di sebelah kiri. Gambar milik ...

 

 

Pakistani politician Saeed Ahmed Khanسعید احمد خانMember of the National Assembly of PakistanIn office1 June 2013 – 31 May 2018ConstituencyNA-170 (Vehari-IV) Personal detailsBorn (1948-08-14) August 14, 1948 (age 75)NationalityPakistaniPolitical partyPakistan Muslim League (N) Saeed Ahmed Khan Manais (Urdu: سعید احمد خان منیس; born 14 August 1948) is a Pakistani politician who was a member of the National Assembly of Pakistan, from June 2013 to May 20...

 

 

French cyclist Laurent FignonFignon at the 1993 Tour de FrancePersonal informationFull nameLaurent Patrick FignonNicknameLe Professeur (The Professor)Born(1960-08-12)12 August 1960Paris, FranceDied31 August 2010(2010-08-31) (aged 50)Paris, FranceHeight1.74 m (5 ft 8+1⁄2 in)Weight67 kg (148 lb; 10 st 8 lb)Team informationDisciplineRoadRoleRiderRider typeAll-rounderProfessional teams1982–1985Renault–Elf–Gitane1986–1989Système U199...

  لمعانٍ أخرى، طالع لياندرو سيلفا (توضيح). هذه المقالة يتيمة إذ تصل إليها مقالات أخرى قليلة جدًا. فضلًا، ساعد بإضافة وصلة إليها في مقالات متعلقة بها. (نوفمبر 2019) لياندرو سيلفا معلومات شخصية الميلاد 7 مارس 1986 (العمر 37 سنة)إريتاما  الطول 1.83 م (6 قدم 0 بوصة) مركز اللع...

 

 

Icelandic alphabet and spelling Eth Þorn A handwriting extract; the Icelandic letters ⟨ð⟩ & ⟨þ⟩ are visible. The Icelandic orthography uses a Latin-script alphabet including some letters duplicated with acute accents; in addition, it includes the letter eth (⟨ð⟩, capital ⟨Ð⟩), transliterated as ⟨d⟩, and the runic letter thorn (⟨þ⟩, capital ⟨Þ⟩), transliterated as ⟨th⟩ (se...

 

 

Vyjayanthimala in Devdas (1955) Vyjayanthimala (born 13 August 1933) is an Indian actress, Bharathanatyam dancer, Carnatic singer, dance choreographer and parliamentarian. She was the highest-paid actress of her time. Regarded as the first female superstar and Megastar of Indian cinema, She made her debut in the Tamil language film at the age of 13 with Vaazhkai in 1949 and in the Telugu film Jeevitham in 1950. She later became one of the most prominent actresses of South Indian cinema and in...

Este artículo o sección sobre transporte necesita ser wikificado, por favor, edítalo para que cumpla con las convenciones de estilo.Este aviso fue puesto el 13 de mayo de 2010. Rutas alimentadoras de Mi Macro Unidad de autobús alimentador de Mi Macro CalzadaLugarUbicación Guadalajara, MéxicoDescripciónTipo AutobúsInauguración 10 de marzo de 2009Rutas 15 rutas alimentadorasCaracterísticas técnicasLongitud 219 km (136,08 mi)Paradas 7 paraderos en estaciones de Mi Macro Calz...

 

 

British TV series or program Baker BoysCreated by Helen Raynor Gary Owen Starring Eve Myles Gareth Jewell Boyd Clack Mark Lewis Jones Matthew Gravelle Cara Readle Steve Meo ComposerAdam LewisCountry of originUnited KingdomProductionRunning timeApprox. 60 minutesOriginal releaseNetworkBBC One WalesRelease23 January (2011-01-23) –8 December 2011 (2011-12-08) Baker Boys is a television drama series produced by BBC Wales and broadcast on BBC One Wales. The series was written...

 

 

Мапа Канади У Канаді існують дві основні системи територіального поділу: адміністративний і переписний. В адміністративному відношенні в різних частинах Канади виділяються від одного (Юкон) до чотирьох (Квебек) рівнів поділу. Зміст 1 Перший рівень 2 Регіональний рівень 3 ...

Sixth letter of many Semitic alphabets This article is about the Semitic letter. For other uses, see WAW. ← He Waw Zayin →PhoenicianHebrewוAramaicSyriacܘArabicوPhonemic representationw, v, o, uPosition in alphabet6Numerical value6Alphabetic derivatives of the PhoenicianGreekϜLatinFCyrillic- Waw (wāw hook) is the sixth letter of the Semitic abjads, including Phoenician wāw

 

 

For the former group in the European Parliament, see Union for Europe of the Nations. This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: European Alliance – news · newspapers · books · scholar · JSTOR (January 2021) (Learn how and when to remove this template message) Political party European Alliance group in ...

 

 

Genre of punk rock This article contains weasel words: vague phrasing that often accompanies biased or unverifiable information. Such statements should be clarified or removed. (March 2009) Christian punkStylistic origins Christian rock punk rock Jesus music Cultural originsEarly 1980s, United Kingdom and United StatesDerivative formsChristian alternative rockSubgenresChristian hardcoreOther topicsList of Christian punk bandsChristian metalChristian socialismChristian communismChristian anarc...

2018 film by Will Gluck Peter RabbitTheatrical release posterDirected byWill GluckScreenplay by Rob Lieber Will Gluck Story by Rob Lieber Will Gluck Based onThe Tale of Peter Rabbitby Beatrix PotterProduced by Will Gluck Zareh Nalbandian Starring Rose Byrne Domhnall Gleeson Sam Neill Daisy Ridley Elizabeth Debicki Margot Robbie James Corden CinematographyPeter Menzies Jr.Edited byChristian GazalJonathan TappinMusic byDominic Lewis[1]Productioncompanies Columbia Pictures[2] Son...

 

 

حولونחולון (بالعبرية: חולון)‏    حولون الموقع الجغرافي تاريخ التأسيس 1940  تقسيم إداري البلد فلسطين[1][2] التقسيم الأعلى منطقة تل أبيب  خصائص جغرافية إحداثيات 32°01′00″N 34°46′00″E / 32.016666666667°N 34.766666666667°E / 32.016666666667; 34.766666666667  المساحة 20 كيلومتر مربع&#...

 

 

Strategi Solo vs Squad di Free Fire: Cara Menang Mudah!