“直接"与“虚拟"调用虚函数 [英] "Direct" vs "virtual" call to a virtual function

查看:30
本文介绍了“直接"与“虚拟"调用虚函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是自学的,因此对很多术语并不熟悉.我似乎无法通过谷歌搜索找到答案:什么是虚拟"与直接"调用虚拟函数?

I am self-taught, and therefore am not familiar with a lot of terminology. I cannot seem to find the answer to this by googling: What is a "virtual" vs a "direct" call to a virtual function?

这与术语有关,与技术无关.我问的是何时将呼叫定义为直接"与虚拟".它与 vtable 或与这些概念的实现有关的任何其他内容无关.

This pertains to terminology, not technicality. I am asking for when a call is defined as being made "directly" vs "virtually". It does not pertain to vtables, or anything else that has to do with the implementation of these concepts.

推荐答案

你的问题的答案在不同的概念层次上是不同的.

The answer to your question is different at different conceptual levels.

  • 在概念语言级别,非正式术语虚拟调用"通常是指根据调用中使用的对象的动态类型解析的调用.根据 C++ 语言标准,这适用于对虚函数的所有调用,但使用函数的限定名称的调用除外.当调用中使用了方法的限定名称时,该调用称为直接调用"

  • At conceptual language level the informal term "virtual call" usually refers to calls resolved in accordance with the dynamic type of the object used in the call. According to C++ language standard, this applies to all calls to virtual functions, except for calls that use qualified name of the function. When qualified name of the method is used in the call, the call is referred to as "direct call"

SomeObject obj;
SomeObject *pobj = &obj;
SomeObject &robj = obj;

obj.some_virtual_function(); // Virtual call
pobj->some_virtual_function(); // Virtual call
robj.some_virtual_function(); // Virtual call

obj.SomeObject::some_virtual_function(); // Direct call
pobj->SomeObject::some_virtual_function(); // Direct call
robj.SomeObject::some_virtual_function(); // Direct call

请注意,您经常会听到人们说通过直接对象对虚函数的调用是非虚函数".但是,语言规范并不支持这种观点.根据语言,所有对虚函数的非限定调用都是相同的:它们根据对象的动态类型进行解析.在[概念]意义上,它们都是虚拟.

Note that you can often hear people say that calls to virtual functions made through immediate objects are "not virtual". However, the language specification does not support this point of view. According to the language, all non-qualified calls to virtual functions are the same: they are resolved in accordance with the dynamic type of the object. In that [conceptual] sense they are all virtual.

在实现级别,术语虚拟调用"通常是指通过某种实现定义的机制分派的调用,该机制实现了虚拟函数的标准要求的功能.通常它是通过与调用中使用的对象相关联的虚拟方法表 (VMT) 来实现的.然而,智能编译器只会在真正需要时才使用 VMT 来执行对虚函数的调用,即在编译时不知道对象的动态类型时.在所有其他情况下,编译器将努力直接调用该方法,即使调用在概念级别上是正式的虚拟".

At implementation level the term "virtual call" usually refers to calls dispatched through some implementation-defined mechanism, that implements the standard-required functionality of virtual functions. Typically it is implemented through Virtual Method Table (VMT) associated with the object used in the call. However, smart compilers will only use VMT to perform calls to virtual functions when they really have to, i.e. when the dynamic type of the object is not known at compile time. In all other cases the compiler will strive to call the method directly, even if the call is formally "virtual" at the conceptual level.

例如,大多数情况下,使用直接对象(而不是指针或对象引用)对虚函数的调用将作为直接调用实现(不涉及 VMT 调度)).这同样适用于从对象的构造函数和析构函数直接调用虚函数

For example, most of the time, calls to virtual functions made with an immediate object (as opposed to a pointer or a reference to object) will be implemented as direct calls (without involving VMT dispatch). The same applies to immediate calls to virtual functions made from object's constructor and destructor

SomeObject obj;
SomeObject *pobj = &obj;
SomeObject &robj = obj;

obj.some_virtual_function(); // Direct call
pobj->some_virtual_function(); // Virtual call in general case
robj.some_virtual_function(); // Virtual call in general case

obj.SomeObject::some_virtual_function(); // Direct call
pobj->SomeObject::some_virtual_function(); // Direct call
robj.SomeObject::some_virtual_function(); // Direct call

当然,在后一种意义上,如果编译器有足够的信息来确定动态类型,则没有什么可以阻止编译器以直接调用的形式实现对虚函数的任何调用(不涉及 VMT 调度)编译时的对象.在上面的简单示例中,任何现代编译器都应该能够将所有调用实现为直接调用.

Of course, in this latter sense, nothing prevents the compiler from implementing any calls to virtual functions as direct calls (without involving VMT dispatch), if the compiler has sufficient information to determine the dynamic type of the object at compile time. In the above simplistic example any modern compiler should be able to implement all calls as direct calls.

这篇关于“直接"与“虚拟"调用虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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