From Gang of Four on the Template Method Pattern:
Three implementation issues are worth noting:
- 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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With