如何实现虚拟函数和虚拟表? [英] How are virtual functions and vtable implemented?

查看:135
本文介绍了如何实现虚拟函数和虚拟表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道C ++中的虚拟函数是什么,但它们是如何在深层实现的?



vtable可以在运行时修改甚至直接访问吗?



vtable是否对所有类都存在,或只有那些至少有一个虚函数的类?



抽象类对于至少一个条目的函数指针只有一个NULL?



单个虚函数减慢整个类?还是只有对虚函数的调用?如果虚拟函数实际上被覆盖,速度会受到影响,或者只要它是虚拟的就没有效果。

解决方案

虚拟功能如何在深层次实现?



C ++中的虚拟函数



virtual function declared,av - table是为类构造的。 v表由包含一个或多个虚函数的类的虚函数的地址组成。包含虚函数的类的对象包含指向存储器中虚拟表的基地址的虚指针。每当有虚函数调用时,v表用于解析到函数地址。包含一个或多个虚拟函数的类的对象包含在存储器中对象的最开始处称为vptr的虚拟指针。因此,在这种情况下对象的大小增加指针的大小。此vptr包含内存中虚拟表的基本地址。注意,虚拟表是类特定的,即,类只有一个虚拟表,而不管它包含的虚拟函数的数量。该虚拟表又包含该类的一个或多个虚拟函数的基地址。在对象上调用虚拟函数时,该对象的vptr将为该类在内存中提供虚拟表的基址。此表用于解析函数调用,因为它包含该类的所有虚拟函数的地址。这是在虚拟函数调用期间如何解析动态绑定。



可以修改vtable,甚至可以在运行时直接访问?



在全球,我相信答案是不。你可以做一些记忆整理来找到vtable,但你仍然不知道函数签名看起来像什么调用它。任何你想用这种能力(语言支持)实现的应该是可能的,而不必直接访问vtable或在运行时修改它。另请注意,C ++语言规范不会指定vtables是必需的,但这是大多数编译器实现虚拟函数的方式。



对于所有对象都存在,或者只有那些至少有一个虚函数的对象?



我相信这里的答案是 因为规范不需要vtables在第一位。然而,在实践中,我相信所有现代编译器只创建一个vtable如果一个类至少有一个虚函数。有一个与vtable相关的空间开销,以及与调用虚函数相对于非虚函数相关的时间开销。



抽象类对于至少有一个条目的函数指针?



答案是它没有指定语言规范,所以它取决于实现。如果未定义(通常不是),调用纯虚函数将导致未定义的行为(ISO / IEC 14882:2003 10.4-2)。实际上,它在vtable中为函数分配一个槽,但不为其分配地址。这使得vtable不完整,需要派生类来实现该函数并完成vtable。一些实现只是在vtable条目中放置一个NULL指针;



请注意,一个抽象类可以为一个纯虚函数定义一个实现,但是这个函数只能使用qualified-id语法(即,完全指定方法名中的类,类似于从派生类调用基类方法)来调用。这是为了提供一个易于使用的默认实现,同时仍需要一个派生类提供一个覆盖。



有一个虚函数会减慢整个类或只有对虚函数的调用?



这是到我的知识的边缘,所以有人请帮助我在这里,如果我错了! p>

我相信只有在类中的虚函数的功能体验与调用虚函数相对于非虚函数相关的时间性能命中。类的空间开销有两种方式。注意,如果有一个vtable,每个类只有一个,而不是每个对象



如果虚拟函数实际上被覆盖,速度会受到影响,或者这是没有影响,只要它是虚拟的?



我不相信执行时间被覆盖的虚拟函数的调用与调用基本虚拟函数相比减少。但是,对于为派生类与基类定义另一个vtable所关联的类,还有额外的空间开销。



其他资源:



http: //www.codersource.net/published/view/325/virtual_functions_in.aspx (通过回传机)

http://en.wikipedia.org/wiki/Virtual_table

http://www.codesourcery.com/public/cxx-abi/abi.html#vtable


We all know what virtual functions are in C++, but how are they implemented at a deep level?

Can the vtable be modified or even directly accessed at runtime?

Does the vtable exist for all classes, or only those that have at least one virtual function?

Do abstract classes simply have a NULL for the function pointer of at least one entry?

Does having a single virtual function slow down the whole class? Or only the call to the function that is virtual? And does the speed get affected if the virtual function is actually overwritten or not, or does this have no effect so long as it is virtual.

解决方案

How are virtual functions implemented at a deep level?

From "Virtual Functions in C++"

Whenever a program has a virtual function declared, a v - table is constructed for the class. The v-table consists of addresses to the virtual functions for classes that contain one or more virtual functions. The object of the class containing the virtual function contains a virtual pointer that points to the base address of the virtual table in memory. Whenever there is a virtual function call, the v-table is used to resolve to the function address. An object of the class that contains one or more virtual functions contains a virtual pointer called the vptr at the very beginning of the object in the memory. Hence the size of the object in this case increases by the size of the pointer. This vptr contains the base address of the virtual table in memory. Note that virtual tables are class specific, i.e., there is only one virtual table for a class irrespective of the number of virtual functions it contains. This virtual table in turn contains the base addresses of one or more virtual functions of the class. At the time when a virtual function is called on an object, the vptr of that object provides the base address of the virtual table for that class in memory. This table is used to resolve the function call as it contains the addresses of all the virtual functions of that class. This is how dynamic binding is resolved during a virtual function call.

Can the vtable be modified or even directly accessed at runtime?

Universally, I believe the answer is "no". You could do some memory mangling to find the vtable but you still wouldn't know what the function signature looks like to call it. Anything that you would want to achieve with this ability (that the language supports) should be possible without access to the vtable directly or modifying it at runtime. Also note, the C++ language spec does not specify that vtables are required - however that is how most compilers implement virtual functions.

Does the vtable exist for all objects, or only those that have at least one virtual function?

I believe the answer here is "it depends on the implementation" since the spec doesn't require vtables in the first place. However, in practice, I believe all modern compilers only create a vtable if a class has at least 1 virtual function. There is a space overhead associated with the vtable and a time overhead associated with calling a virtual function vs a non-virtual function.

Do abstract classes simply have a NULL for the function pointer of at least one entry?

The answer is it is unspecified by the language spec so it depends on the implementation. Calling the pure virtual function results in undefined behavior if it is not defined (which it usually isn't) (ISO/IEC 14882:2003 10.4-2). In practice it does allocate a slot in the vtable for the function but does not assign an address to it. This leaves the vtable incomplete which requires the derived classes to implement the function and complete the vtable. Some implementations do simply place a NULL pointer in the vtable entry; other implementations place a pointer to a dummy method that does something similar to an assertion.

Note that an abstract class can define an implementation for a pure virtual function, but that function can only be called with a qualified-id syntax (ie., fully specifying the class in the method name, similar to calling a base class method from a derived class). This is done to provide an easy to use default implementation, while still requiring that a derived class provide an override.

Does having a single virtual function slow down the whole class or only the call to the function that is virtual?

This is getting to the edge of my knowledge, so someone please help me out here if I'm wrong!

I believe that only the functions that are virtual in the class experience the time performance hit related to calling a virtual function vs. a non-virtual function. The space overhead for the class is there either way. Note that if there is a vtable, there is only 1 per class, not one per object.

Does the speed get affected if the virtual function is actually overridden or not, or does this have no effect so long as it is virtual?

I don't believe the execution time of a virtual function that is overridden decreases compared to calling the base virtual function. However, there is an additional space overhead for the class associated with defining another vtable for the derived class vs the base class.

Additional Resources:

http://www.codersource.net/published/view/325/virtual_functions_in.aspx (via way back machine)
http://en.wikipedia.org/wiki/Virtual_table
http://www.codesourcery.com/public/cxx-abi/abi.html#vtable

这篇关于如何实现虚拟函数和虚拟表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆