C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 23:
[23.2] That last FAQ confuses me. Is it a different strategy from the other ways to use virtual functions? What's going on?

Yes, it is a different strategy. Yes, there really are two different basic ways to use virtual functions:

  1. Suppose you have the situation described in the previous FAQ: you have a method whose overall structure is the same for each derived class, but has little pieces that are different in each derived class. So the algorithm is the same, but the primitives are different. In this case you'd write the overall algorithm in the base class as a public method (that's sometimes non-virtual), and you'd write the little pieces in the derived classes. The little pieces would be declared in the base class (they're often protected, they're often pure virtual, and they're certainly virtual), and they'd ultimately be defined in each derived class. The most critical question in this situation is whether or not the public method containing the overall algorithm should be virtual. The answer is to make it virtual if you think that some derived class might need to override it.
  2. Suppose you have the exact opposite situation from the previous FAQ, where you have a method whose overall structure is different in each derived class, yet it has little pieces that are the same in most (if not all) derived classes. In this case you'd put the overall algorithm in a public virtual that's ultimately defined in the derived classes, and the little pieces of common code can be written once (to avoid code duplication) and stashed somewhere (anywhere!). A common place to stash the little pieces is in the protected part of the base class, but that's not necessary and it might not even be best. Just find a place to stash them and you'll be fine. Note that if you do stash them in the base class, you should normally make them protected, since normally they do things that public users don't need/want to do. Assuming they're protected, they probably shouldn't be virtual: if the derived class doesn't like the behavior in one of them, it doesn't have to call that method.

For emphasis, the above list is a both/and situation, not an either/or situation. In other words, you don't have to choose between these two strategies on any given class. It's perfectly normal to have method f() correspond to strategy #1 while method g() corresponds to strategy #2. In other words, it's perfectly normal to have both strategies working in the same class.