【问题标题】:When should I use templates instead of inheritance, and vice versa? [closed]什么时候应该使用模板而不是继承,反之亦然? [关闭]
【发布时间】:2011-10-03 13:38:24
【问题描述】:

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

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

以代码某些部分的类似策略模式的参数化为例:

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

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

void FileParser::Parse(ParsingAlgorithm* p)
{
   m_whatevertypeofvaluesineed = p->Parse(whateverparametersyouneed);
}

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

不过,使用模板也可以轻松实现:

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

   private:
      Parser m_parser;
   //...
}

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

【问题讨论】:

标签: c++ templates inheritance


【解决方案1】:

如果您在编译时知道要操作哪些对象,那么使用模板的静态多态性通常是最快的方法,并且它生成的代码更简洁(不需要显式继承)。它也可以更通用,因为您不限于强大的类层次结构。

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

我自己的看法:

  • 尽可能使用模板,这很舒服
  • 使用继承来分解代码(但不要有异构集合),但要小心切片。
  • 不用担心虚拟调用的性能问题
  • 有时您别无选择,并且希望通过使用指针的痛苦来拖累异构集合

【讨论】:

    【解决方案2】:

    模板提供编译时多态性,而不是继承提供的运行时多态性。我更喜欢尽可能使用模板。

    Templates and Inheritance上的这篇文章详细讲解。

    【讨论】:

      【解决方案3】:

      模板通常在运行时性能更高,因为更多的工作是在编译时完成的。另一方面,它们可能更复杂,因此难以编写和理解。因此,最好在可以并且不会使整个解决方案过于复杂的情况下使用它们。

      对于您的示例,它们在功能上并不完全等效:第一个变体允许 并且 要求您在运行时创建解析器的实例,而第二个变体要求程序员在他写代码。

      【讨论】:

        【解决方案4】:

        我的建议是在这种情况下都不要使用,而是为每种文件类型使用单独的函数;

            Stream stream = open(filepath);
        
            Image image = ParseBMP(stream);
            // ...or
            Image image = ParseJPG(stream);
        

        没有必要让事情变得比实际更复杂。

        【讨论】:

        • 您是对的,但我的示例只是简单地说明了可能出现“继承与模板”问题的情况类型。
        • 我不同意。使用不同的功能是违反开闭原则en.wikipedia.org/wiki/Open/closed_principle
        • 以前从未听说过那个校长,但我觉得它有点邪恶。
        猜你喜欢
        • 2010-11-14
        • 2011-12-07
        • 1970-01-01
        • 2010-10-23
        • 2017-10-21
        • 2012-04-11
        • 2020-08-19
        • 2011-04-01
        • 2015-09-10
        相关资源
        最近更新 更多