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

时间:2009-02-25 02:51:30

标签: c++ virtual-functions

关于动态多态性的这个问题提出了

The CRTP。但是,据称这种模式仅对静态多态性有用。我所看到的设计似乎受到虚拟函数调用的快速阻碍,因为hinted at here.甚至2.5倍的加速也会很棒。

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

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

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

3 个答案:

答案 0 :(得分:18)

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

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

    虚拟方法调用与静态绑定调用相比具有非常小的性能开销。我建议你看看SO question.

    的答案

答案 1 :(得分:3)

我同意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();
}

类似

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的变体可能稍微优雅/安全,但要注意这些功能有自己的开销,可能与虚拟调用相当。

如果某些类方法是no-ops,并且它使您无法调用它们,或者如果函数包含常见的循环不变代码并且优化器设法提升它,那么您很可能会看到上述改进走出循环。

答案 2 :(得分:-1)

你可以去Ole C Route并使用工会。虽然这也可能很混乱。