C++中是否存在多态性的替代方案?

cas*_*der 8 c++ virtual-functions

关于动态多态性的问题中提出了CRTP.但是,据称这种模式仅对静态多态性有用.我所看到的设计似乎受到虚拟函数调用的快速阻碍,如此处暗示的那样. 加速甚至2.5倍将是太棒了.

有问题的类很简单,可以完全内联编码,但是直到运行时才会知道将使用哪些类.此外,它们可以以任何顺序链接,将性能损失归咎于伤害.

任何建议(包括如何在这种情况下使用CRTP)欢迎.

编辑:谷歌搜索提到功能模板.这看起来很有希望

m-s*_*arp 18

多态性字面意思是多个(多边形)形式(变形).在静态类型语言(例如C++)中,存在三种类型的多态性.

  1. Adhoc多态性:这在C++中作为函数和方法重载最好.基于将调用参数的编译时类型与函数或方法签名匹配,相同的函数名称将绑定到不同的方法.
  2. 参数多态:在C++中,这是模板和你可以用它做的所有有趣的事情,如CRTP,专业化,部分特化,元编程等.再次这种多态性,相同的模板名称可以根据模板做不同的事情参数是编译时多态.
  3. 子类型多态性:最后,当我们在C++中听到多态性这个词时,我们会想到这一点.这是派生类覆盖虚拟函数以专门化行为的地方.指向基类的相同类型的指针可以根据它指向的具体派生类型具有不同的行为.这是在C++中获取运行时多态性的方法.

如果直到运行时才知道将使用哪些类,则必须使用子类型多态,这将涉及虚函数调用.

静态方法调用与静态绑定调用相比具有非常小的性能开销.我恳请你看看这个问题的答案.


tim*_*day 4

我同意 m-sharp 的观点,即你不会避免运行时多态性。

如果您重视优化而不是优雅,请尝试替换说

void invoke_trivial_on_all(const std::vector<Base*>& v)
{
  for (int i=0;i<v.size();i++)
    v[i]->trivial_virtual_method();
}
Run Code Online (Sandbox Code Playgroud)

与类似的东西

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...
  }
}
Run Code Online (Sandbox Code Playgroud)

它不漂亮,当然不是 OOP(更多的是对你在旧的“C”中可能做的事情的回归),但如果虚拟方法足够简单,你应该得到一个没有调用的函数(受足够好的编译器和优化选项的影响)。使用dynamic_cast或typeid的变体可能稍微更优雅/安全,但要注意这些功能有自己的开销,无论如何可能与虚拟调用相当。

您最有可能看到上述改进的地方是,如果某些类方法是无操作的,并且它使您免于调用它们,或者如果函数包含常见的循环不变代码并且优化器设法将其从环形。

  • if-else 链很可能会变慢。分支机构相当昂贵。不仅如此,必须链接它们意味着你在时间关键部分有 O(N) 行为......更好的比较是 switch 与虚函数调用。即使如此,速度也应该相似...... (2认同)