简体   繁体   English

这种间接的 function 调用有什么好处?

[英]What's the advantage of this indirect function call?

I found the following code in a library:我在库中找到了以下代码:

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

Now I'm wondering: Why would you use this indirection?现在我想知道:为什么要使用这种间接方式? Could there be any reasons why the above would be better than the simple alternative:是否有任何理由说明上述方法比简单的替代方法更好:

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

This is the Non-Virtual Interface Idiom (NVI).是非虚拟接口惯用语(NVI)。 That page by Herb Sutter has a good bit of detail about it. Herb Sutter 的那页有很多关于它的细节。 However, temper what you read there with what the C++ FAQ Lite says here and here .但是,请使用 C++ FAQ Lite此处此处所说的内容来调整您在此处阅读的内容。

The primary advantage of NVI is separating interface from implementation. NVI 的主要优点是将接口与实现分离。 A base class can implement a generic algorithm and present it to the world while its subclasses can implement the details of the algorithm through virtual functions.一个基类 class 可以实现一个通用算法并将其呈现给世界,而它的子类可以通过虚函数实现算法的细节。 Outside users are shielded from changes in the algorithm details, especially if you later decide you want to do add pre- and post-processing code.外部用户不受算法细节更改的影响,尤其是当您后来决定要添加预处理和后处理代码时。

The obvious disadvantage is that you have to write extra code.明显的缺点是您必须编写额外的代码。 Also, private virtual functions are confusing to a lot of people.此外, private虚函数让很多人感到困惑。 Many coders mistakenly think you can't override them.许多编码人员错误地认为您不能覆盖它们。 Herb Sutter seems to like private virtuals, but IMHO it's more effective in practice to follow the C++ FAQ Lite's recommendation and make them protected . Herb Sutter 似乎喜欢private虚拟,但恕我直言,在实践中遵循 C++ FAQ Lite 的建议并使其protected更有效。

This is often called a Template-Hook pair (aka Hotspot), coined by Wolfgang Pree.这通常被称为由 Wolfgang Pree 创造的 Template-Hook 对(又名 Hotspot)。

See this PDF , PowerPoint , HTML请参阅此PDFPowerPointHTML

One reason for doing the indirection as you call it is that things often can/has to be setup prior a method, and some cleaing post a method call.像您所说的那样进行间接处理的一个原因是,通常可以/必须在方法之前设置一些东西,并且一些方法会在方法调用之后进行清除。 In the subclasses you only need to supply the necessary behaviour without doing the setup and cleaning ...在子类中,您只需要提供必要的行为而无需进行设置清理......

This is the template pattern.这是模板模式。 The foo method contains code that must be executed by all subclasses. foo 方法包含必须由所有子类执行的代码。 It makes more sense when you look at it like this:当你这样看时,它会更有意义:

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;
};

It's nicer than the alternative, which is to try to remember to call the common code in each subclass individually.它比替代方法更好,即尝试记住单独调用每个子类中的公共代码。 Inevitably, someone makes a subclass but forgets to call the common code, resulting in any number of problems.不可避免地,有人创建了一个子类但忘记调用公共代码,从而导致许多问题。

If a subclass could change the definition of foo_?, but the consumers needed a static function (for efficiency)?如果子类可以更改 foo_? 的定义,但消费者需要 static function(为了提高效率)? Or for a delegation pattern?或者对于委托模式?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM