据我了解,所有成员函数在D中都是虚拟的,但如果编译器发现它们从未被覆盖,则编译器可以自由地使函数成为非虚函数。
我不清楚的是当你编译一个没有覆盖成员函数的模块然后将那个模块导入你覆盖成员函数的其他地方时会发生什么。我认为它不会重新编译原始模块。它是否只是假设任何具有外部链接的成员函数是虚拟的?
答案 0 :(得分:5)
默认情况下,所有D成员函数都是虚拟的。我不认为有任何编译器实际上将非虚拟函数作为优化。你可以通过将类或函数标记为“最终”来手动完成。
答案 1 :(得分:2)
除了无法虚拟化的模板化函数外,FeepingCreature大多是正确的。
答案 2 :(得分:2)
如何实现它是编译器和链接器特定的。但是,当您在本地实例化类时,可以优化虚拟函数调用的一种常见情况。然后可以在此范围内直接执行函数调用,因为类的类型在编译时是完全已知的。这可以在编译器级别完成。
除此之外,如果链接器实现的函数实现永远不会被覆盖,那么链接器可能会进行优化并用该类上的直接函数调用替换虚函数调用。特别是,如果从未派生类,则可以直接执行对成员函数的所有调用。就好像链接器会尽可能地插入'final'关键字。 (链接器可能不会将此优化应用于导出的类和函数,因为链接器不知道函数是否在其他库或可执行文件中被覆盖。)
答案 3 :(得分:1)
我相信FeepingCreature是正确的,但我认为你可以假设,如果编译器直接从源代码创建可执行文件,那么这些优化只会被考虑。