C ++: Differences between templates of NVI methods and templates?

What is the difference between NVI ( Non-Virtual Interface ) and Method Template ?

They seem very similar, and I read both that they are basically the same and that they are subtly different from the fact that Template is something more general.

+7
c ++ design-patterns template-method-pattern non-virtual-interface
source share
2 answers

NVI is an idiom, a template template is a template. NVI is an implementation of a template method template using dynamic dispatch in C ++; you can also create template methods in C ++ using metaprogramming templates to eliminate dynamic sending.

The pattern is more general than the idiom, and languages ​​can use different idioms to implement the pattern.

+11
source share

As already mentioned, NVI is a prosaic idiom associated with the category of languages. Herb Sutter was among them because he helps conclude contracts:

  • class invariants
  • function contracts (statements on the passed parameters and return value)
  • repetitive operations (e.g. logging)
  • control over the generated exceptions (a bad idea, though;))

However, the implementation may vary significantly, for example, another example of an NVI implementation is combining it with Pimpl:

class FooImpl; class Foo { public: enum type { Type1, Type2 }; Foo(type t, int i, int j); int GetResult() const; private: FooImpl* mImpl; }; 

And for implementation:

 struct FooImpl { virtual ~FooImpl(); virtual int GetResult() const; }; class FooType1: public FooImpl { public: FooType1(int i, int j); virtual int GetResult() const; private: /// ... }; 

I always found that this conveyed the point better. Do you get it?

The main thing is that virtual is an implementation detail. And exposing implementation details in an interface is a bad idea because you can change them.

In addition, implementation details are typically related to binary compatibility. For example, adding a new virtual method to a class can change the layout of a virtual table (a common implementation technique) and thus enable binary compatibility. On gcc, you need to make sure that you add it last (among the virtual ones) if you want to keep compatibility.

Using the above NVI + Pimpl combination, there is no virtual (not even closed) in the open class. Memory layout compatible with feedback. We have achieved binary compatibility.

Here we use several templates at once:

  • Template method
  • Strategy (since we can change the pointer as desired)
  • Factory (to decide which implementation we will get)
+8
source share

All Articles