可能重复:
Pure virtual functions may not have an inline definition. Why?
正如标题所说,为什么?如何(不纯)虚函数,它可以是内联格式吗?而且我想知道真正的原因。谢谢!
答案 0 :(得分:4)
虚拟函数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
的类型是A
而不是B
。因此,如果他不能安全地假设*a
的类型,编译器就不会这样做。
在此示例中,编译器可以成功并安全地假设不需要虚拟化:这实际上取决于编译器和优化级别。
在某些情况下,编译器可以安全地假设不需要虚拟化,只有在这些情况下,内联关键字才有意义。
即使您使用关键字inline
声明一个函数,该函数也可能没有内联。
无论如何手动添加inline
关键字大部分时间都不是一个好主意,今天的编译器很好并且在必要时自动内联函数。
通过添加inline
,您可能会在某些情况下降低性能,因此不要滥用它是一种很好的做法
答案 1 :(得分:2)
嗯,纯虚函数肯定可以内联标记。
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();
}