这种间接函数调用的优点是什么?

时间:2009-03-19 17:50:09

标签: c++ inheritance function abstract-class virtual-functions

我在库中找到了以下代码:

class Bar {
public:
  bool foo(int i) {
   return foo_(i);
  }
private:
  virtual bool foo_(int i) = 0;
};

现在我想知道:你为什么要使用这个间接?可能有任何理由说明为什么上述会比简单的替代方案更好:

class Bar {
public:
  virtual bool foo(int i) = 0;
};

4 个答案:

答案 0 :(得分:10)

这是Non-Virtual Interface Idiom(NVI)。 Herb Sutter的那篇页面有很多细节。但是,使用C ++ FAQ Lite所说的herehere来调整你所阅读的内容。

NVI的主要优点是将接口与实现分离。基类可以实现通用算法并将其呈现给世界,而其子类可以通过虚函数实现算法的细节。外部用户可以避免算法细节的变化,特别是如果您以后决定要添加预处理和后处理代码。

明显的缺点是你必须编写额外的代码。此外,private虚拟功能让很多人感到困惑。许多程序员错误地认为你无法覆盖它们。 Herb Sutter似乎喜欢虚拟private,但恕我直言,在实践中遵循C ++ FAQ Lite的建议更有效,并使它们成为protected

答案 1 :(得分:3)

这通常被称为模板 - 钩子(a.k.a Hotspot),由Wolfgang Pree创造。

请参阅此PDFPowerPointHTML

在调用它时执行间接的一个原因是,在方法之前通常可以/必须设置,并且有些清理 post 方法调用。在子类中,您只需提供必要的行为,而无需执行设置清理 ......

答案 2 :(得分:2)

这是模板模式。 foo方法包含必须由所有子类执行的代码。当你这样看时,它会更有意义:

class Bar {
public:
  bool foo(int i) {
   // Setup / initialization / error checking / input validation etc 
   // that must be done for all subclasses
   return foo_(i);
  }
private:
  virtual bool foo_(int i) = 0;
};

它比替代方案更好,它试图记住单独调用每个子类中的公共代码。不可避免地,有人会创建一个子类但忘记调用公共代码,从而导致任何数量的问题。

答案 3 :(得分:0)

如果一个子类可以改变foo_?的定义,但是消费者需要一个静态函数(为了效率)?或者代表团模式?