虚拟表/调度表
据我对CPP的了解,每个类都有自己的vtable。
然而此维基百科链接提到:
对象的调度表将 包含对象的地址 动态绑定方法。方法 调用是通过获取 方法的地址来自对象的地址 调度表。调度表是 对于属于的所有对象都相同 同一个类,因此 通常在他们之间共享。
有人可以解释一下吗?
谢谢 !
From what I know of CPP, each class has its own vtable.
However this wikipedia link mentions:
An object's dispatch 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
dispatch table. The dispatch table is
the same for all objects belonging to
the same class, and is therefore
typically shared between them.
Can someone please shed some light.
Thanks !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有时用一个例子更容易理解:
因此,给定一个 Derived 类型的对象,它可能看起来像:
“Derived”类型的 Vtable 看起来像这样:
请注意,由于“methodC”不是虚拟的,所以它不在 vtable 中根本不。另请注意,Derived 类的所有实例都将具有指向同一共享 vtable 对象的 vtable 指针(因为它们具有相同的类型)。
尽管 C++ 和 Java 的实现略有不同,但思想并非不兼容。从概念的角度来看,主要区别在于 Java 方法是“虚拟的”,除非声明为“final”。在 C++ 中,必须显式给出关键字“virtual”才能使函数位于 vtable 中。任何不在 vtable 中的内容都将使用对象的编译时类型而不是运行时类型进行分派。
It's sometimes easier to understand with an example:
So, given an object of type Derived it might look like:
With the Vtable for type "Derived" looking something like:
Note that since "methodC" was not virtual, it is not in the vtable at all. Also note that all instances of class Derived will have a vtable pointer to the same, shared vtable object (since they have the same type).
Though the implementations for C++ and Java are slightly different, the ideas are not incompatible. The key difference, from a conceptual standpoint, is that Java methods are "virtual" unless declared "final". In C++ the keyword "virtual" must be given explicitly for the function to be in the vtable. Anything not in vtable will be dispatched using the compile-time types rather than the runtime type of the object.
是的,编译器和运行时对虚拟方法的处理方式不同。
Java: java 中的所有方法默认都是虚拟的。这意味着在继承中使用时任何方法都可以被重写,除非该方法被声明为final或static。
从 VM 规范,
C++:
每当类成员函数被声明为 virtual 时,编译器都会创建一个
内存中的虚拟表,其中包含声明为的所有函数指针
虚拟在该类中。这使得运行时多态性成为可能(即找出所需的
运行时函数)。虚函数表还有一个额外的指针
vtable 的对象。由于这个额外的指针和虚表增加了大小
对于对象,类设计者需要明智地声明函数为虚函数。
在基础对象指针上调用方法时的事件顺序是:
通过vtable指针间接调用该函数。
Yes, virtual methods are treated differently by the compiler and the runtime.
Java : All methods in java are virtual by default. That means that any method can be overridden when used in inheritance, unless that method is declared as final or static.
From the VM Specification,
C++ :
Whenever a class member function is declared as virtual, the compiler creates a
virtual table in memory which contains all function pointers that are declared as
virtual in that class. This enables run time polymorphism (i.e. finding out the desired
function at run time). Virtual function tables also have an additional pointer in the
object to the vtable. As this additional pointer and the vtable increases the size of
the object, a class designer needs to be judicious about declaring functions virtual.
The sequence of events upon calling a method on the base object pointer is :
Invoke the function indirectly through the vtable pointer.
每个具有虚函数的类(即在 Java 中只是“每个类”)都有自己的
vtable
。每个对象都隐藏了对其类 vtable 的引用。因此,同一类的对象具有相同的引用。当您调用虚拟方法时,编译器通常会进行查找:
被翻译成某种东西
有时,如果编译器可以推断出特定类型的对象,它可以发出静态调用而不是虚拟方法。因此,代码
可以转换为
通常比虚拟调用执行得更快的代码。
Every class having virtual functions (i.e. in Java it's just 'every class') has its own
vtable
. Each object has hidden a reference to it's class vtable. So, objects of the same class have identical references.When you make call of virtual method compiler usually makes a lookup:
is translated into something
Sometimes, if compiler can deduce particular type of object, it can emit static call instead of virtual. So, code
can be translated into
Which will usually execute faster than virtual call.
该引用指出每个对象都有一个调度表,该表可以在类之间共享,因为它们对于同一类的所有实例都是相同的。 IE 每个类都有它自己的 vtable。
That quote is pointing out that each object has a dispatch table, which can be shared among the class since they are the same for all instances of the same class. I.E. Each class has it's own vtable.