问题
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;
};
回答1:
This is the Non-Virtual Interface Idiom (NVI). That page by Herb Sutter has a good bit of detail about it. However, temper what you read there with what the C++ FAQ Lite says here and here.
The primary advantage of NVI is separating interface from implementation. 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. 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. 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
.
回答2:
This is often called a Template-Hook pair (a.k.a Hotspot), coined by Wolfgang Pree.
See this PDF, PowerPoint, HTML
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...
回答3:
This is the template pattern. The foo method contains code that must be executed by all subclasses. 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.
回答4:
If a subclass could change the definition of foo_?, but the consumers needed a static function (for efficiency)? Or for a delegation pattern?
来源:https://stackoverflow.com/questions/663280/whats-the-advantage-of-this-indirect-function-call