我什么时候应该使用模板而不是继承,反之亦然?

Tra*_*isG 17 c++ inheritance templates

在许多情况下,问题甚至不会问自己,因为有时继承提供了模板无法提供的必要功能.例如,当我需要通过一个基类型(多态)来处理不同的类型时,我需要使用继承.

但是,在某些情况下,问题可以通过继承和模板来解决.

举例来说,代码的某些部分采用类似策略模式的参数化:

文件解析器的一个解决方案可能如下所示:

class FileParser
{
   //...
   public:
      void Parse(ParsingAlgorithm* p);
   //...
}

void FileParser::Parse(ParsingAlgorithm* p)
{
   m_whatevertypeofvaluesineed = p->Parse(whateverparametersyouneed);
}
Run Code Online (Sandbox Code Playgroud)

其中ParsingAlgorithm是一个抽象基类,它提供了一些基本方法,需要由任何喜欢为FileParser类实现特定解析器的人继承.

但是,使用模板可以轻松实现相同的目的:

template <class Parser>
class FileParser
{
   //...
   public:
      void Parse()
      {
           m_whatevertypeofvaluesineed = m_parser.Parse(whateverparametersyouneed);
      }

   private:
      Parser m_parser;
   //...
}
Run Code Online (Sandbox Code Playgroud)

是否有一些通用规则可用于决定是使用模板还是继承?或者我应该尽可能简单地使用模板,以避免虚拟函数之类的运行时开销?

Tri*_*ner 18

如果您在编译期间知道要操作的对象是什么,那么使用模板的静态多态通常是最快的方法,它会产生更简洁的代码(不需要显式继承).它也可以更通用,因为您不限于强类层次结构.

如果你想要运行时多态,那么你别无选择,只能使用指针,继承和虚函数的轻微开销.

我自己的意见:

  • 尽可能使用模板,这很舒服
  • 使用继承来分解代码(但不要使用异构集合),但要小心切片.
  • 不要担心虚拟调用的性能问题
  • 有时候你别无选择,而且你想要使用指针来拖延杂乱的集合