[Exceptional C++ Style] Item 18 - Virtuality

Kevlin Henney kevlin at curbralan.com
Sun Jan 9 05:25:17 EST 2005


In message 
<C3571D9EA82596468B7C6D662C82B8240546F752 at RED-MSG-32.redmond.corp.microso
ft.com>, Herb Sutter <hsutter at microsoft.com> writes
>>
>> If one takes the time to analyse where the supposed benefits are, it
>> becomes clear that in all cases NVI is either an inferior solution
>> compared to another (eg interception) or an architectural
>misconception.
>
>I'm curious about this. Can you elaborate with examples?

Examples I have seen for justification (some of which I know you 
certainly don't agree with) include the following:

- Ability to change the perceived behaviour of an interface by adding 
more features in at the base class level. This is one manifestation of 
the classic fragile base class problem, and breaking clients is 
generally considered a bad thing. Any line of reasoning that is 
justified by making it easier to break functional contracts is not a 
good one!

- Ability to add in monitor-like locking on objects at will. Although 
this is an operational rather than a functional change, it shows a deep 
misunderstanding of threading and designing interfaces, hierarchies and 
implementations for such environments. My instinct is that where a 
programmer believes NVI is the right bet to help them with this domain 
of design, threading capabilities should be disabled on their platform 
;-)

- Introduction of design by contract. See my other posting.

- Ability to add in instrumentation or other extra-functional behaviour 
into a framework or specific deployment. This is the realm in which 
delegation-based techniques excel, and the track record for such 
techniques is exceptionally good. Whether in the form of Decorator, 
Interceptor, Proxy, etc, this provides the configurability and 
extensibility in a way that is orthogonal to the hierarchy being worked 
on. This is the domain of aspect-oriented design, and in non AOP systems 
delegation is normally considered the least intrusive approach to 
expressing and adding these independent elements.

This is certainly not an exhaustive list, but it is a sampler.

>In particular, NVI has been rediscovered several times,

I have seen common design pitfalls repeated many times in code that I 
have reviewed in different companies. Repetition is not sufficient to 
justify something as being a good idea.

>and in
>particular WinFX has perhaps unique needs -- shipping a large
>platform-level framework that will be heavily extended, so that once we
>ship we are extremely constrained about the kinds of changes you can
>make to base classes.

I would be interested in knowing more detail about this example, because 
it is not one that I am familiar with. I would be interested to know in 
what ways it is intended to be extended, and what other techniques were 
considered.

>For example, if you expose a public virtual
>function and ship that way, you can't ever (easily) retrofit
>instrumentation or other pre- and post-actions around the virtual call.

I'm interested: why not? Interception and transparent 
forwarding/wrapping through delegation are the common techniques for 
dealing with this notion in the design palette of many other frameworks. 
As I am unfamiliar with WinFX, I may be missing another constraint or 
perhaps there is a specific example that brings the point home more 
solidly.

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