可能重复:
纯虚函数可能没有内联定义。为什么?
正如标题所说,为什么?那么(非纯)虚函数怎么样,它可以是内联格式吗?我想知道真正的原因。谢谢!
99% 的情况下都不能使用虚函数,inlined
因为函数指针在运行时使用vtable
.
虚函数的目的是被子类重载。一个例子 :
class A
{
virtual int foo() { return 1; }
}
class B : public A
{
virtual int foo() { return 2; }
}
int main(void)
{
B b;
A *a = &b;
return a->foo();
}
主函数将返回 2 而不是 1。
如果编译器内联函数,它将返回 1,因为编译器只能假设*a
isA
和 not的类型B
。因此,如果编译器不能安全地假设*a
.
在此示例中,编译器可以成功且安全地假定不需要虚拟化:这实际上取决于编译器和优化级别。
在某些情况下,编译器可以安全地假设不需要虚拟化,并且只有在这些情况下 inline 关键字才有意义。
即使您使用关键字声明函数inline
,该函数也可能不会被内联。
无论如何手动添加inline
关键字在大多数情况下都不是一个好主意,今天的编译器很好并且在必要时自动内联函数。通过添加inline
您可能会在某些情况下降低性能,因此最好不要滥用它
好吧,纯虚函数当然可以标记为内联。
struct Base
{
virtual void Func() const = 0;
};
inline void Base::Func() const
{ std::cout<<"Base\n"; }
struct Concrete : Base
{
virtual void Func() const;
};
inline void Concrete::Func() const
{ Base::Func(); std::cout<<"Concrete\n"; }
inline
此外,在编译器可以静态确定需要调用的函数的情况下,可以内联虚函数(与关键字的关系不是很密切)。例如:
int main(void)
{
Concrete o;
o.Func();
}
完整演示:http: //ideone.com/zlxn8I
并查看这个相关问题:LTO、去虚拟化和虚拟表