在这个关于动态多态性的问题中建议使用 CRTP 。然而,据称这种模式只对静态多态有用。正如这里所暗示的,我正在查看的设计似乎受到虚函数调用的快速阻碍。 即使是 2.5 倍的加速也很棒。
有问题的类很简单,可以完全内联编码,但是直到运行时才知道将使用哪些类。此外,他们可能会以任何顺序被束缚,将性能侮辱堆积到伤害上。
欢迎提出任何建议(包括在这种情况下如何使用 CRTP)。
编辑:谷歌搜索出现了函数模板的提及。这些看起来很有希望。
多态性的字面意思是多种(多)形式(变形)。在静态类型语言(例如 C++)中,存在三种类型的多态性。
如果直到运行时才知道将使用哪些类,则必须使用涉及虚函数调用的子类型多态。
与静态绑定调用相比,虚拟方法调用的性能开销非常小。我敦促您查看此SO 问题的答案。
我同意 m-sharp 的观点,即您不会避免运行时多态性。
如果您重视优化而不是优雅,请尝试替换 say
void invoke_trivial_on_all(const std::vector<Base*>& v)
{
for (int i=0;i<v.size();i++)
v[i]->trivial_virtual_method();
}
有类似的东西
void invoke_trivial_on_all(const std::vector<Base*>& v)
{
for (int i=0;i<v.size();i++)
{
if (v[i]->tag==FooTag)
static_cast<Foo*>(v[i])->Foo::trivial_virtual_method();
else if (v[i]->tag==BarTag)
static_cast<Bar*>(v[i])->Bar::trivial_virtual_method();
else...
}
}
它不漂亮,当然不是 OOP(更多的是回归到你可能在好的旧“C”中做的事情),但如果虚拟方法足够简单,你应该得到一个没有调用的函数(取决于足够好的编译器和优化选项)。使用 dynamic_cast 或 typeid 的变体可能更优雅/安全,但要注意这些功能有自己的开销,无论如何可能与虚拟调用相当。
您最有可能从上面看到改进的地方是,如果某些类方法是无操作的,并且它使您免于调用它们,或者如果函数包含常见的循环不变代码并且优化器设法将其从环形。
您可以走 Ole C 路线并使用工会。尽管这也可能很混乱。