c – 对虚拟功能的“直接”与“虚拟”调用

前端之家收集整理的这篇文章主要介绍了c – 对虚拟功能的“直接”与“虚拟”调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是自学成才,所以我不熟悉很多术语.我似乎无法通过谷歌搜索找到答案:什么是虚拟功能的“虚拟”与“直接”调用

这涉及术语,而不是技术性.我要求将呼叫定义为“直接”与“虚拟”.
它不适用于vtable,也不属于与这些概念的实现有关的任何其他内容.

解决方法

在不同的概念层面,您的问题的答案是不同的.

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

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

请注意,您经常可以听到人们说通过直接对象调用虚拟函数是“非虚拟”.但是,语言规范不支持这种观点.根据该语言,对虚函数的所有非限定调用都是相同的:它们根据对象的动态类型进行解析.在[概念]意义上,它们都是虚拟的.
>在实现级别,术语“虚拟调用”通常是指通过某些实现定义的机制调度的调用,该机制实现虚拟函数的标准所需功能.通常,它通过与呼叫中使用的对象相关联的虚拟方法表(VMT)来实现.但是,智能编译器仅在必要时才使用VMT来执行对虚函数调用,即在编译时不知道对象的动态类型时.在所有其他情况下,编译器将努力直接调用方法,即使该调用在概念级别上是正式的“虚拟”.

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

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调度).在上面的简单示例中,任何现代编译器都应该能够将所有调用实现为直接调用.

猜你在找的C&C++相关文章