0

可能重复:
纯虚函数可能没有内联定义。为什么?

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

4

2 回答 2

5

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,因为编译器只能假设*aisA和 not的类型B。因此,如果编译器不能安全地假设*a.

在此示例中,编译器可以成功且安全地假定不需要虚拟化:这实际上取决于编译器和优化级别。

在某些情况下,编译器可以安全地假设不需要虚拟化,并且只有在这些情况下 inline 关键字才有意义。

即使您使用关键字声明函数inline,该函数也可能不会被内联。

无论如何手动添加inline关键字在大多数情况下都不是一个好主意,今天的编译器很好并且在必要时自动内联函数。通过添加inline您可能会在某些情况下降低性能,因此最好不要滥用它

于 2013-01-02T13:08:41.733 回答
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、去虚拟化和虚拟表

于 2013-01-02T13:16:21.423 回答