其类型在编译时已知的虚拟方法

发布于 2024-11-11 23:02:31 字数 302 浏览 3 评论 0原文

如果我这样做:

Dog dog; //class with virtual methods
Cat cat; //class from same base as Dog

dog.eat(); //call virtual method
cat.eat(); //call virtual method

那么 eat() 将是正常的方法调用,并且不需要 v 表 - 正确吗? 我可以假设它的运行方式与非虚拟方法相同吗?

(是的,我知道编译器如何处理虚函数并不在标准中 - 我想知道大多数编译器是做什么的)

If I do something like:

Dog dog; //class with virtual methods
Cat cat; //class from same base as Dog

dog.eat(); //call virtual method
cat.eat(); //call virtual method

Then the eat()s will be normal method calls and will not require the v-table - correct?
I can assume that it would run identical to a non-virtual method?

(and yes, I know that how compilers handle virtual functions is not in the standard - I want to know what most compilers do)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

听你说爱我 2024-11-18 23:02:31

当您使用 object.member 时 - 您不会取消引用指针,因此对 virtual 方法没有影响。仅当您有一个可以多态的指针并且使用动态调度时,Virtual 才会生效。

例如:

Cat cat;
Animal *cat2 = &cat;
cat.eat(); // direct call
//... a lot of other code and function calls that pass cat2 around, to avoid optimization
cat2->eat(); // dynamic dispatch

编辑按评论更正

When you're using object.member - you're not dereferencing a pointer, so there's no effect to the virtual methods. Virtual comes into effect only when you have a pointer which can be polymorphic and dynamic dispatch is used.

For example:

Cat cat;
Animal *cat2 = &cat;
cat.eat(); // direct call
//... a lot of other code and function calls that pass cat2 around, to avoid optimization
cat2->eat(); // dynamic dispatch

edit corrected per comments

等往事风中吹 2024-11-18 23:02:31

如果分析显示大多数时间使用某种类型,则 Visual Studio 能够将虚拟调用优化为直接调用。

虚拟呼叫推测 – 如果
虚拟呼叫,或通过其他呼叫
函数指针,经常指向一个
某些功能,配置文件引导
优化可以插入一个
有条件执行的直接调用
经常定位的功能,以及
直接调用可以内联。

请参阅 MSDN 上的配置文件引导优化

常规的“去虚拟化”(即其他答案所提到的)可以在不分析应用程序的情况下完成,并且非常常见。

GCC 自动启用此优化,但具体标志为 -fdevvirtualize

尝试将呼叫转换为虚拟呼叫
直接调用的功能。这是
在程序内完成并且
过程间作为间接的一部分
内联(-findirect-inlined)和
过程间常数传播
(-fipa-cp)。在-O2级别启用,
-O3,-Os。

来自 GCC 优化选项

Visual Studio is able to optimize a virtual call into a direct call if profiling shows that a certain type is used most of the time.

Virtual Call Speculation – If a
virtual call, or other call through a
function pointer, frequently targets a
certain function, a profile-guided
optimization can insert a
conditionally-executed direct call to
the frequently-targeted function, and
the direct call can be inlined.

See Profile Guided Optimization on MSDN.

Regular "devirtualization" (i.e. what the other answers allude to) can be done without profiling the app, and is pretty common.

GCC enables this optimization automatically, but the specific flag is -fdevirtualize:

Attempt to convert calls to virtual
functions to direct calls. This is
done both within a procedure and
interprocedurally as part of indirect
inlining (-findirect-inlining) and
interprocedural constant propagation
(-fipa-cp). Enabled at levels -O2,
-O3, -Os.

from GCC Optimize Options.

清欢 2024-11-18 23:02:31

如果静态类型在编译时已知,则无需使用 vtable,因为无论如何要调用的函数都是已知的。

大多数编译器都会看到这一点。

If the static type is known at compile time there is no need to use the vtable, as the function to call in known anyway.

Most compilers will see this.

过期以后 2024-11-18 23:02:31

我想说的是,大多数编译器都会进行这种优化。如果您已经进行了分析并且它确实很重要,那么唯一确定的方法就是检查生成的反汇编。

I would say that yes, most compilers would do this optimization. If you've profiled and it actually matters, the only way to know for sure is to check the disassembly generated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文