调用非虚拟基础方法时,C中是否有虚拟继承的惩罚/成本?

在C编译代码中使用虚拟继承时,在基类中调用常规函数成员时,是否使用虚拟继承?示例代码:

class A {
    public:
        void foo(void) {}
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};

// ...

D bar;
bar.foo ();
最佳答案
可能是的,如果您通过指针或引用调用成员函数,并且编译器无法绝对确定指针或引用指向或引用的对象的类型。例如,考虑:

void f(B* p) { p->foo(); }

void g()
{
    D bar;
    f(&bar);
}

假设对f的调用没有内联,编译器需要生成代码以找到A虚拟基类子对象的位置,以调用foo。通常这个查找涉及检查vptr / vtable。

如果编译器知道您正在调用该函数的对象的类型(尽管如您的示例所示),则不应该有开销,因为函数调用可以静态调用(在编译时)。在您的示例中,已知动态类型为D(它不能是其他任何东西),因此可以在编译时计算虚拟基类子对象A的偏移量。

转载注明原文:调用非虚拟基础方法时,C中是否有虚拟继承的惩罚/成本? - 代码日志