C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 23:
[23.4] When should someone use private virtuals?

When you need to make specific behavior in a base class customizable in derived classes, while protecting the semantics of the interface (and/or the base algorithm therein), which is defined in public methods that call private virtual methods.

One case where private virtuals show up is when implementing the Template Method design pattern. Some experts, e.g., Herb Sutter's C/C++ Users Journal article Virtuality, advocate it as a best practice to always define virtual methods private, unless there is a good reason to make them protected. Virtual methods, in their view, should never be public, because they define the class' interface, which must remain consistent in all derived classes. Protected and private virtuals define the class' customizable behavior, and there is no need to make them public. A public virtual method would define both interface and a customization point, a duality that could reflect weak design.

By the way, it confuses most novice C++ programmers that private virtuals can be overridden, let alone are valid at all. We were all taught that private members in a base class are not accessible in classes derived from it, which is correct. However this inaccessibility by the derived class does not have anything to do with the virtual call mechanism, which is to the derived class. Since that might confuse novices, the C++ FAQ formerly recommended using protected virtuals rather than private virtuals. However the private virtual approach is now common enough that confusion of novices is less of a concern.

You might ask, What good is a method that the derived class can't call? Even though the derived class can't call it in the base class, the base class can call it which effectively calls down to the (appropriate) derived class. And that's what the Template Method pattern is all about.

Think of "Back to the Future." Assume the base class is written last year, and you are about to create a new derived class later today. The base class' methods, which might have been compiled and stuck into a library months ago, will call the private (or protected) virtual, and that will effectively "call into the future" - the code which was compiled months ago will call code that doesn't even exist yet - code you are about to write in the next few minutes. You can't access private members of the base class - you can't reach into the past, but the past can reach into the future and call your methods which you haven't even written yet.

Here is what that Template Method pattern looks like:

class MyBaseClass {
  void myOp();

  virtual void myOp_step1() = 0;
  virtual void myOp_step2();

void MyBaseClass::myOp()
  // Pre-processing...

  myOp_step1();  //call into the future - call the derived class
  myOp_step2();  //optionally the future - this one isn't pure virtual

  // Post-processing...

void MyBaseClass::myOp_step2()
  ...   //this is "default" code - it can optionally be customized by a derived class
In this example, public method MyBaseClass::myOp() implements the interface and basic algorithm to perform some operation. The pre- and post-processing, as well as the sequence of step 1 and step 2, are intentionally fixed and cannot be customized by a derived class. If MyBaseClass::myOp() was virtual, the integrity of that algorithm would be seriously compromised. Instead, customization is restricted to specific "pieces" of the algorithm, implemented in the two private virtual methods. This enforces better compliance of derived classes to the original intent embodied in the base class, and also makes customization easier - the derived class' author needs to write less code.

If MyBaseClass::myOp_step2() might need to be called by the derived class, for example, if the derived class might need (or want) to use that code to simplify its own code, then that can be promoted from a private virtual to a protected virtual. If that is not possible because the base class belongs to a different organization, as a band-aid the code can be copied.

(At this point I can almost read your thoughts: "What? Copy code??!? Are you KIDDING??!? That would increase maintenance cost and duplicate bugs!! Are you CRAZY??!?" Whether I'm crazy remains to be seen, but I am experienced enough to realize life sometimes paints you into a corner. If the base class can't be modified, sometimes the "least bad" of the bad alternatives is to copy some code. Remember, one size does not fit all, and "think" is not a four-letter word. So hold your nose and do whatever is the least bad thing. Then shower. Twice. But if you risk the team's success because you are waiting for some third party to change their base class, or if you use #define to change the meaning of private, you might have chosen a worse evil. And oh yea, if you copy the code, mark it with a big fat comment so I won't come along and think you are crazy!! Good.)

On the other hand, if you are creating the base class and if you aren't sure whether derived class's might want to call MyBaseClass::myOp_step2(), you can declare it protected just in case. And in that case, you'd better put a big fat comment next to it so Herb doesn't come along and think you're crazy! Either way, somebody is going to think you're crazy.