虚函数在c++中总是不能内联吗?
Is it always true that virtual function cannot be inlined in C++?
据说虚函数不能内联。如果一个函数被声明为虚函数,它就不能在代码中的任何地方内联,或者它只在某些情况下适用吗?(如。(从基指针调用方法与从引用调用方法,等等)
不,虚函数确实可以内联。虚拟调度仅在多态调用虚拟方法时使用(即,在指针或对象引用上)。但是,当在对象值上调用虚方法时,不使用虚分派,编译器可以自由地内联它认为合适的方法
给定:
struct T {
virtual void foo() { /* something */ }
};
使用多态性 (如果您通过pointer-to-T
或reference-to-T
调用foo()
)
T* ptr = get_ptr_somehow();
ptr->foo();
如果编译器知道 T
是其继承树中的唯一节点,它可以放弃虚拟调用并可能内联函数。然而,这是一个非常不可能的场景,我怀疑它是否能被探测到。在所有其他情况下,由于运行时调度,内联是不实际的。
静态调度 (如果你在一个bog标准对象上调用foo()
)
T obj;
obj.foo();
在这种情况下,编译器知道obj
的动态类型是T
,因此它不需要虚拟分派,因此如果它愿意,可以内联函数代码。
T* ptr = get_ptr_somehow();
ptr->T::foo();
在这种情况下,编译器不知道obj
的动态类型,但它知道它将调用哪个函数,知道它不需要虚拟分派,因此可以内联函数代码,如果它想。
虚成员函数基本上是一个指向函数的指针,该指针根据类层次结构实现指向要调用的正确函数。(注意,它不一定是一个指针,但它经常这样实现,因为它似乎是这个抽象的最有效的实现)。
这表明只在运行时确定将调用哪个函数。
那么如何内联一个只在运行时知道的函数呢?不可能。
除非你有一个JIT编译器:)the_drow
正确的。这是不常见的,您可能会在启动时损失一些性能,但仍然是正确的。
例如,在堆栈上或类内部声明的对象不需要对其被调用的虚函数进行动态分派,因为编译器知道堆栈上所有对象的类型,所以基本上是任何值。虚函数调度只能通过指针或引用进行。
当涉及到优化时,很少是正确的。一般来说,如果编译器无法判断对象的实际类型,则必须在运行时解析虚函数。如果你有一个实际的实例(Class vs . Class&),那么编译器可以确定。如果你有一个参考,它将不得不猜测;如果调用函数本身是内联的,它可能会以这种方式标识静态类型,也可能不会。
注意,在这种情况下,指针和引用之间没有区别。在任何一种情况下,都可以获得运行时多态性。
虚函数(方法)可以内联。请记住,inline
关键字是对编译器的建议,而不是要求。
内联代码很像将函数原样粘贴到可执行文件中需要的地方。没有创建独立的函数。
当存在指向内联函数的指针(由编译器在内部或由程序员在外部)时,可以不使用内联。当有指向内联函数的指针时,必须有一个内联函数实例。编译器可以自由地内联代码,但必须在静态(固定)位置有一个实例来满足指针。
我的建议是内联简单的,少于5行代码,不使用分析器的方法。记住,内联通常是将代码放在头文件中。当方法的代码被更改时,依赖于头文件的所有翻译单元都必须重新构建。这在大型系统中可能代价高昂。一般来说,大块的代码只应该在之后内联,它们被验证,并且只是为了提高性能分析器规定的效率。
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么虚函数不能是静态的和全局的?
- 是否可以将函数导入命名空间,但不能导出它?
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 为什么我不能在 constexpr lambda 函数中使用 std::tuple
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 为什么我不能将引用作为 std::async 的函数参数传递
- 不能调用构造函数
- 为什么我不能引用指向实例化对象的函数的指针?
- 不能对类型化模板使用 STL 函数
- 为什么函数名不能与返回名类型相同?
- 不能制作需要布尔成员函数的C++20概念
- 为什么我不能直接从返回指针的函数返回对指针的引用?
- 为什么继承的受保护构造函数不能公开?
- 为什么我不能创建一个 TSubclassOf<> 在 SpawnActor() 函数中使用?
- Clang-Format 不能正确分配函数参数