[Exceptional C++ Style] Item 18 - Virtuality

Kevlin Henney kevlin at curbralan.com
Fri Jan 7 02:58:04 EST 2005


In message <31d4d63b05010606048abbf40 at mail.gmail.com>, Timothy Wright 
<tcw321 at gmail.com> writes
>  My designs that tend to be
>large and couple many classes give me the biggest problems in the long
>run, they smell.  So I am always looking for best practices like NVI
>to use, bits of knowledge so I don't have to learn by painful
>experience.  But, as people pointed out, NVI has problems too.

NVI will not help you with such partitioning. The problem is that the 
classes are large and coupled. Techniques that further divide and 
decouple are what you need, eg the use of call-out interfaces to break 
cyclic dependencies.

>Ultimately, I find out what smells and what does not by experience and
>I have not found (maybe it can't exist) a good design book that gives
>me more ideas on what is good and what is bad.  Design Pattern and
>refactoring books seem to come closest. The problem with the advice
>"keep it simple but not too simple" is that it does not answer
>specific questions.

Indeed. This is why a rich vocabulary of techniques is needed when 
considering any design. Few potted solutions exist out of the box.

>Is NVI good?

For most definitions of "good", no it isn't. If you consider NVI a 
design smell, you will not go too far wrong.

>Should I use the pimpl design
>(another Herb's suggestions) everywhere?

Definitely not. And I don't think that Herb suggests using it 
everywhere. It is technique that can be applied to great effect on 
certain (not all) classes in your system to isolate build and binary 
dependencies. Any concrete class whose internal structure is subject to 
frequent change, but attracts many users and a long build time, is a 
potential candidate. Another technique is to introduce an interface 
class, which is particularly suitable at the base of a class hierarchy. 
You can even combine the two approaches for concrete implementations in 
a class hierarchy that still attract too many dependencies. Likewise, 
other techniques such as using unnamed namespaces to isolate 
implementation specifics within .cpp files can also help. All of these 
techniques play the role of minimising the footprint of an 
implementation in the header.

>What is simple and what adds
>too much complication?  Keeping member variables private is considered
>a good idea but does add complexity but everyone feels that it is a
>good price to pay.

It does rather depend on what is meant by "complexity". To reiterate a 
point I made before, encapsulation is an abstraction process that has 
the effect of simplifying class usage and class evolution. It is easy to 
find examples that benefit from hiding data representation almost the 
moment you think about it -- in fact, there are so many, you end up 
tripping over them! There is plenty of evidence concerning the benefits 
of such encapsulation, and plenty of evidence that its absence is more 
often a problem than a solution -- simplistic rather than simple.

>I guess that is why ACCU and these discussion groups exist. :-)

Indeed :-)

Kevlin
-- 
____________________________________________________________

   Kevlin Henney                   phone:  +44 117 942 2990
   mailto:kevlin at curbralan.com     mobile: +44 7801 073 508
   http://www.curbralan.com        fax:    +44 870 052 2289
   Curbralan: Consultancy + Training + Development + Review
____________________________________________________________



More information about the Effective-cpp mailing list