15

From Gang of Four on the Template Method Pattern:

Three implementation issues are worth noting:

  1. Using C++ access control. In C++, the primitive operations that a template method calls can be declared protected members. This ensures that they are only called by the template method. Primitive operations that must be overridden are declared pure virtual. The template method itself should not be overridden; therefore you can make the template method a nonvirtual member function.

"This ensures that they are only called by the template method." is not true, is it? As the primitive methods (if some are virtual rather than pure virtual for example) could also be called from a derived class. Is it not true that only declaring the primitive methods private ensures they are only called by the template method? The private virtual primitive methods can then still be implemented (or reimplemented) in subclasses to provide the specialised behaviour which is required within the algorithm defined in the template method in the superclass.

See "Virtuality" from Herb Sutter:

http://www.gotw.ca/publications/mill18.htm

Where he states that:

Guideline #2: Prefer to make virtual functions private. Guideline #3: Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected.

I don't see any requirement within the GoF Template Method pattern for derived classes to invoke base class implementations of virtual functions, so why do Gang of Four recommend making these functions protected rather than private?

Nawaz
  • 353,942
  • 115
  • 666
  • 851
Paul Caheny
  • 1,281
  • 3
  • 11
  • 16

1 Answers1

11

The answer is pretty simple:

Design Patterns dates from 1994. At this time C++ was still evolving heavily into the language that we know today – the previous standard was finalised in 1998! Compilers were buggy and didn’t support important features that we now take for granted.

But more importantly, many things hadn’t been discovered (in particular by mainstream programmers) yet. Take template metaprogramming, the whole of which was only “stumbled upon” around the same time.

I highly suspect that the same is true for private virtual functions: The GoF simply weren’t aware that this was legal C++. Or if it was, it hadn’t established itself as a convention.

In fact, most C++ code that was considered “good” in 1994 would be considered overly complex and error-prone today, even without taking C++11 into account.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 3
    The historical perspective is more or less right---in 1995, I don't think it even occurred to most C++ programmers that you could override a private function. (And the virtual functions in `std::streambuf` are protected, not private.) Still, even today, I think that there are some people who prefer `protected` rather than `private` for such functions. They certainly must be known to the derived class, and for those people, `private` means private, at least to human readers, if not to the compiler. – James Kanze Mar 07 '12 at 14:02
  • 1
    @James I can attest to that … until recently I was unaware that this was legal, and found it highly unintuitive at first … – Konrad Rudolph Mar 07 '12 at 14:06
  • Thanks. I suspected this was the answer but I had Stephen Dewhurst's C++ Common Knowledge (2005) to hand before asking the question and it raised my suspicion that there was something more to the protected/private argument that I was missing. Its chapter on the Template Method mentions that it is "typically" implemented to call protected virtual functions, which it goes on to use in the code example. It doesn't make any mention of the private versus protected issue for the primitive functions called by the template method otherwise. – Paul Caheny Mar 07 '12 at 14:49