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

标签 c++ runtime overhead virtual-inheritance

当我们从其基类调用 常规函数 成员时,在 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虚拟基类子对象的位置,以便调用。通常这种查找涉及检查 vptr/vtable。

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

关于c++ - 调用非虚拟基方法时,C++ 中的虚拟继承是否有任何惩罚/成本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5553850/

相关文章:

c++ - 得到一个类的两个实例?

android - Android 中的 OpenCV 4.0.1 链接失败

configuration - 让 log4j 在运行时了解配置的变化

asp.net-mvc - 根据运行时 session 值解决 Autofac 的服务实现

c++ - MPI 和标准输入开销?

c++ - 在虚继承中调用非虚基方法是否有额外的开销?

c++ - 以下代码是否调用未定义的行为?

c++ - 如何为类重载运算符 +()

java - 如何从java运行cygwin脚本

delphi - 在长循环中处理消息时如何最大限度地减少开销