你会选择什么?虚函数,模板还是分支?

时间:2011-12-29 04:19:14

标签: c++ templates polymorphism

我遇到了一个C ++设计问题,可以在虚函数,模板和分支之间进行选择。这三种实现如下所列。我最终选择了第二种实现方式,它看起来很棘手,但在低延迟设计方面具有最佳性能。

虚拟功能实施:

class Channel : public BaseChannel
{
  void packet(...) { for (...) message(...); }
  virtual void message(...)=0;
};

class ChannelA : public Channel
{
  struct Header {...}
  void message(...) { ... }
}
class ChannelB : public Channel
{
  struct Header {...}
  void message(...) { ... }
}

模板实施:

template <typename TImpl>
class Channel : public BaseChannel
{
  void packet(...) { for (...) message(...); }
  void message(...);
};

class ChannelA : public Channel<ChannelA>
{
  struct Header {...}
  void message(...) { ... }
}
class ChannelB : public Channel<ChannelB>
{
  struct Header {...}
  void message(...) { ... }
}
template <typename TImpl>
inline void Channel<TImpl>::message(...) { static_cast<TImpl*>(this)->message(); }

分支机构实施:

class Channel : public BaseChannel
{
  void packet(...) { for (...) message(...); }
  struct HeaderA {...}
  struct HeaderB {...}
  void message(...)
  {
      if (isHeaderA(...)) messageA(...);
      else if (isHeaderB(...)) messageB(...);
  }
  void messageA(...) { ... }
  void messageB(...) { ... }
};

2 个答案:

答案 0 :(得分:2)

虚拟主义有自己的开销(虽然是最小的),尽管有一个例外,编译器可以应用优化虚拟调度来编译时间评估,如果可以的话。这就像把它留给编译器的想法。

如果您可以通过CRTP实现相同的多态行为,那么您应该使用模板为您提供慷慨的优势。

所以是的第二种方法是要走的路。

答案 1 :(得分:0)

您的预期剂量是多少?

  1. 多态性 - 易于扩展对象,支持不同的对象,你不会遇到抛物线if语句,但你需要做更多的编码和设计,而且很难理解一个谁不具备OO概念或设计模式概念。

  2. 模板 - 这似乎是(3)中的分支实现,因为您需要单独存储一个对象。

  3. 分支 - 基本且易于编码,但是当您扩展这些对象时会很痛苦,例如,当您拥有OjbectA-ObjcetJ时代码应该如何。嗯,这是抛物线的对象:)

  4. (1)和(3)都需要运行时性能开销,并且(1)具有比(3)更好的性能,因为我已经完成了实验。 (2)会使你的程序更大,就像(3)。

    总之,您可以选择(1)您是否有不同的派生类或将来可能会增加,或者您想要您的表现,但您可以选择(3)如果您没有太多的反对意见派生,或者你不需要一个好的表现,或者你不想做更多的编码。