[Exceptional C++ Style] Item 18 - Virtuality
Jon Jagger
jon at jaggersoft.com
Tue Jan 4 08:11:36 EST 2005
And as if by magic Kevlin sends an email explaining that he too has many
doubts about the advice....
>C++ standard library already follows this guideline.
>The standard library has:
>6 public virtual functions, and 142 nonpublic virtual
>functions.
>
>The author mentions one WinFX (the object-oriented
>successor to the Win32 API and the programming model
>for Longhorn) design guideline which recommends using
>‘Template Method’ pattern and discusses why this
>pattern is such a good idea.
>
Playing the devils advocate much of the design of the C++ library and
Win32 API leaves one feeling, how shall I put it, somewhat "empty"
>
>Traditionally, programmers write base classes using
>public virtual functions which simultaneously specify
>both the interface and the customizable behaviour.
>
>
Surely it is a base class that contains any implementation that is
"guilty" of specifying both the interface and some behaviour (whether it
be customizable or not)?
>Every public virtual function is forced to serve two
>audiences, the outside callers of the class and
>derived classes.
>
But if the base class contains only pure virtual functions it serves the
purpose of representing the point where the outside and the inside
touch. And it does not get weighed down with supposed commonality. What
is wrong with having a clear separation of concerns and putting
commonality into an ABC (containing some implementation) below the
interface (containing only pure virtual functions). Pushing
implementation up into the base class is what causes the base class to
start serving two masters.
>A different approach should be
>considered as a public virtual function inherently has
>two significantly different jobs, and two competing
>audiences.
>
>Herb presents Nonvirtual Interface (NVI) pattern which
>is a more restricted idiom with a form similar to that
>of Gang of Four’s Template Method pattern.
>
>//A modern base class, using Nonvirtual Interface
>//(NVI) to separate interface from internals.
>class Widget
>{
>public :
> //Stable, nonvirtual interface.
> //
> intProcess( Gadget& ); // uses DoProcess()
> bool IsDone(); // uses DoIsDone()
> //
>private :
> virtual intDoProcessPhase1( Gadget& );
> virtual intDoProcessPhase2( Gadget& );
> virtual bool DoIsDone()
> //
>};
>
>
This separates the interface from the internals. But, I'm afraid, IMHO
it only does so superficially. As Kevlin keenly observed it seems to be
overly conerned with "form". And it's more coupled than a truly abstract
base class. It's an accident waiting to happen - an instantiable class
which you're invited to derive from. It's just asking to be sliced. Is
this is the actual code from Herb's book? I hope not.
Cheers
JJ
More information about the Effective-cpp
mailing list