为什么纯虚函数不能内联?

时间:2013-01-02 13:07:26

标签: c++

  

可能重复:
  Pure virtual functions may not have an inline definition. Why?

正如标题所说,为什么?如何(不纯)虚函数,它可以是内联格式吗?而且我想知道真正的原因。谢谢!

2 个答案:

答案 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();
}

完整演示:http://ideone.com/zlxn8I

并查看相关问题:LTO, Devirtualization, and Virtual Tables