[Qt-interest] Non-Virtual Interface Idiom

Herb Sutter herb.sutter at gmail.com
Tue Dec 21 02:48:45 CET 2010


 <Oliver.Knoll <at> comit.ch> writes:
> On 2010-12-19 Piotr Piotr Dobrogost wrote:
> 
> > One of design rules made popular by Herb Sutter is Non-Virtual Interface 
Idiom
> > explained in the article "Virtuality" in C/C++ Users Journal, 19(9), 
September 2001
> > (http://www.gotw.ca/publications/mill18.htm), which can be summarized in 
the
> > guideline "Prefer to make interfaces nonvirtual, using Template Method."

BTW, I subsequently tightened up the wording a little on this to emphasize 
that this is different from the Template Method pattern. The current advice 
can be found in C++ Coding Standards Item 39, "Consider making virtual 
functions nonpublic, and public functions nonvirtual."


> I think Herb Sutter did not understand the point of interfaces: he mixes 
implementation with interfaces.
> When I talk about "interfaces" I think "Java interfaces", and in C++ that 
renders to pure virtual classes
> (in my understanding of "interfaces").

First, the above was said to a C++ audience, and "interface" was used in the 
sense of "the public interface of a class" (i.e., not of a Java- or C#-style 
interface).

A Java/C#-style interface is its own thing, and of course it naturally 
consists of only what in C++ are called pure virtual functions. (Aside: Note 
that Java/C# interface methods are subtly different from virtual methods even 
in those languages. Briefly, interface methods should be thought of as being 
implemented, whereas virtual methods are overridden, and there is a 
difference. People often don't grok that distinction at first.)


> But for interfaces this totally does not make sense to me, 

Right, it's about classes. That classes can choose to implement NVI is a 
significant advantage of classes over interfaces. However, in those 
environments you have to stick with interfaces most of the time because of the 
SI restriction.


> and the fact that this practise has had no impact
> since 2001 (the time this article was published) tells me that others 
agree ;)

I don't know how much impact the article itself had, but NVI has been 
independently rediscovered lots of times (including long before my article), 
and is followed assiduously in lots of popular frameworks including the C++ 
standard library (which has only one public virtual function, exception::what)
and the .NET Frameworks (see http://tinyurl.com/22ksqxp) which includes 
explicit advice to make virtual methods protected rather than public (private 
is not an option in .NET) -- the advice is sound and applies perfectly well, 
and of course it applies to _classes_ rather than to interfaces.

It's just good engineering to decouple two separate and independent things:

  (a) the interface presented to the outside world (callers)

  (b) the customization hooks presented to derived classes (implementers)

because they are different audiences with different needs. A base class 
provides both of them, and they are usually best decoupled (and people 
continue to rediscover).

Interfaces don't allow you to decouple them, and interfaces are best thought 
of as specifying base class public methods. That is, in Java and C#, it's good 
design to consider implementing interface methods using public _nonvirtual_ 
(sealed/final) methods in the class that delegate to new nonpublic virtual 
methods.

Herb






More information about the Qt-interest-old mailing list