如何使用多重继承内联虚拟
how to inline virtual with multiple inheritance
请不要bash我或说我问这个问题是错误的或多重继承是邪恶的。这个问题是为了更好地理解 C++ 编译器的工作原理。我知道 inline
语句用于提示编译器用源代码替换函数调用,编译器可以选择是否内联函数。如果您可以强制执行 inline
函数,那就太好了,但这并不是我真正要解决的问题。我想要做的是能够创建一段代码,该代码在一个地方编写,并由编译器复制并粘贴到其他地方。我写的代码看起来像这样:
struct base
{
virtual double eval() = 0; // should be no eval function for the
};
struct foo : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct bar : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct baz : public base
{
virtual double eval() overrides
{
return //baz eval
}
};
struct FooBarBaz : public foo, public bar, public baz
{
virtual double eval() final
{
return foo::eval() + bar::eval() + baz::eval();
}
};
编译器会生成与此等效的内容:
struct base
{
virtual double eval() = 0; // should be no eval function for the
};
struct foo : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct bar : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct baz : public base
{
virtual double eval() overrides
{
return //baz eval
}
};
struct FooBarBaz : public foo, public bar, public baz
{
virtual double eval() final
{
return /*foo eval*/ + /*bar eval*/ + /*baz eval*/
}
};
有人告诉我使用 <type_traits>
是解决此问题的方法,如果这是真的,我想知道如何获得所需的结果。如果没有,我想知道该怎么做
编译器是否决定内联取决于它编码的启发式方法……但没有理由不内联对 foo::eval
、bar::eval
和 [= 的调用12=] 来自 FooBarBaz::eval
因为资格禁用动态调度。
也就是说,当编译器遇到一个合格的调用foo::eval
时,它会执行foo
级别的那个成员函数的最终覆盖。它不会使用 vtable
(无论如何都会以无限递归结束,因为最终的覆盖程序将是 FooBarBaz::eval
.
除此之外,您应该阅读 虚拟继承,FooBarBaz
有 3 个 [=19] 类型的子对象=], 可能不是你想要的...
请不要bash我或说我问这个问题是错误的或多重继承是邪恶的。这个问题是为了更好地理解 C++ 编译器的工作原理。我知道 inline
语句用于提示编译器用源代码替换函数调用,编译器可以选择是否内联函数。如果您可以强制执行 inline
函数,那就太好了,但这并不是我真正要解决的问题。我想要做的是能够创建一段代码,该代码在一个地方编写,并由编译器复制并粘贴到其他地方。我写的代码看起来像这样:
struct base
{
virtual double eval() = 0; // should be no eval function for the
};
struct foo : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct bar : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct baz : public base
{
virtual double eval() overrides
{
return //baz eval
}
};
struct FooBarBaz : public foo, public bar, public baz
{
virtual double eval() final
{
return foo::eval() + bar::eval() + baz::eval();
}
};
编译器会生成与此等效的内容:
struct base
{
virtual double eval() = 0; // should be no eval function for the
};
struct foo : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct bar : public base
{
virtual double eval() overrides
{
return //foo eval
}
};
struct baz : public base
{
virtual double eval() overrides
{
return //baz eval
}
};
struct FooBarBaz : public foo, public bar, public baz
{
virtual double eval() final
{
return /*foo eval*/ + /*bar eval*/ + /*baz eval*/
}
};
有人告诉我使用 <type_traits>
是解决此问题的方法,如果这是真的,我想知道如何获得所需的结果。如果没有,我想知道该怎么做
编译器是否决定内联取决于它编码的启发式方法……但没有理由不内联对 foo::eval
、bar::eval
和 [= 的调用12=] 来自 FooBarBaz::eval
因为资格禁用动态调度。
也就是说,当编译器遇到一个合格的调用foo::eval
时,它会执行foo
级别的那个成员函数的最终覆盖。它不会使用 vtable
(无论如何都会以无限递归结束,因为最终的覆盖程序将是 FooBarBaz::eval
.
除此之外,您应该阅读 虚拟继承,FooBarBaz
有 3 个 [=19] 类型的子对象=], 可能不是你想要的...