[Exceptional C++ Style] Item 18 - Virtuality

Hammond, Peter peter.hammond at amsjv.com
Fri Jan 7 06:55:56 EST 2005




> -----Original Message-----
> From: Kevlin Henney [mailto:kevlin at curbralan.com]
> Sent: 04 January 2005 14:17
> To: effective-cpp at accu.org
> Subject: Re: [Exceptional C++ Style] Item 18 - Virtuality
>
<snip> 
> 
> When I teach class hierarchy design, one of the considerations I 
> advocate is that pure virtual functions should be overridden and 
> non-pure virtual functions should not be. In other words, provide new 
> implementations but don't replace existing implementations. This has 
> some very useful consequences in terms of design and design 
> questions, 
> and tends to lead to more clearly structured class hierarchies, with 
> clearer responsibilities and looser coupling than most other 
> approaches. 
> What you end up with is a hierarchy that is purely abstract 
> at its roots 
> and fully concrete at its leaves, with the middle taking the 
> slack and 
> strain of implementation refactoring. There are many ways of 
> justifying 
> such an architectural approach, but the view that you should not 
> disinherit code is perhaps the simplest in terms of 
> generating such an 
> architecture.
> 
> The role of the middle layer is to factor out commonality in the 
> concrete layer, and it is here that use of Template Method or, often 
> better, a delegation-based alternative such as Strategy, Interceptor, 
> Object Adapter, etc, can come into play. It is in this layer that NVI 
> could be seen to have a possible role. However, unless an 
> application of 
> NVI actually factors out some commonality, it may be better to Remove 
> Middle Man (http://www.refactoring.com/catalog/removeMiddleMan.html).
> 
<snip>
> Kevlin

Sorry to come late to the discusion, and overlap the next item. At first I
thought I agreed with the original guideline, but now I'm not so sure. I
think what I agree with is using Template Method, but I'm slightly confused
still. I'm not sure that I see the distinction between NVI and Template
Method. 

If there are to be methods overridden, I'd much rather see a clear
distinction between what the outside world calls on the base, what the base
calls on the dervied and what if anything the derived calls on the base -
what the base provides to the world, what the base requires of its children,
and what the base provides for its children. That would indeed be in the
middle layer of a three layer hierarchy.

There are certainly many cases where pure abstract interfaces (I think that
is the right term, a class with only pure virtual fuctions) are useful in
promoting encapsulation. But an abstract base class with implementation does
not seem like an abomination to me, in the right circumstances - these being
mainly that there are no package boundaries (for some value of "package") to
enforce separation across. If we consider always starting from the three
layer approach, sometimes we will remove the middle man, but perhaps
sometimes we remove the pure abstract interface, if that is seen to be not
adding anything? And then we end up at NVI. It seems that, like any other
guideline, there is an unspoken "when it is appropriate" there. Perhaps the
guideline should be more like the last guideline in this item: "Make
interfaces either nonvirtual or pure virtual".

In confusion,
Pete.

********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************



More information about the Effective-cpp mailing list