Simulated Dynamic Binding

Excerpts from a thread on http://groups.yahoo.com/group/wtl/ around 2003/04/28.

 template <class _T>
 class CMyXMLBase : public CExpatImpl <_T>
I can't figure out why everyone keeps doing that. In this case, it's probably a doggerel version of the AbstractTemplate? DesignPattern. If so, make CExpatImpl into a concrete class and an abstract interface (IExpat, for example). Then CMyXMLBase inherits IExpat and resolves any methods we need in it, such as OnStartElement or OnEndElement.

Appendix A of ATL Internals talks about this, as well as an article on devx [1]. It's been called "simulated dynamic binding", "ATL style inheritance", "upside down inheritance", "static polymorphism", [the "CuriouslyRecurringTemplate pattern"] and other things. It's used quite a bit in ActiveTemplateLibrary / WindowsTemplateLibrary for various BaseClasses. It's not mutually exclusive to an interface, but is often used in conjunction with an interface (such as IDispatchImpl, IProvideClassInfo2Impl, etc.). It's also the technique used by of all the "MixIn" windowing base classes of ATL / WTL (CWindowImpl, etc.).

Using this approach, in the base class you do something like:

   T* pT = static_cast<T*>(this);
   pT->OverrideableFunction();
It's essentially like having "OverrideableFunction" be a virtual function, but with a couple of benefits:

  1. It saves at least 2 levels of indirection (with a virtual function pointer and virtual function table) at run-time.
  2. The calculations for a static_cast<> are performed at compile time, so the code can be optimized better because it's a compile-time thing rather than a run-time thing. (The compiler might even be able to inline the function call - which would be impossible if using a virtual function).
  3. It can possibly save you from needing a v-table and virtual function pointer altogether - which saves at least the 4 byte virtual function pointer per instance, plus the size of the virtual table.
  4. Your base class doesn't have to define the method - thus acting like a PureVirtual function that has to be defined in derived classes or you get compile errors.
  5. You can call static methods on the derived class. (And technically you could use public member variables as well - both static and non-static.)
  6. Other stuff I'm forgetting I'm sure.

Item #5 can't be done with virtual classes and functions even if you wanted to. Just one of the many examples of this in the ActiveTemplateLibrary is when you are making a COM object with ATL: you define "BEGIN_COM_MAP", which expands to you defining a handful of static methods and members that the base class CComObjectRootEx calls to help implement QueryInterface.

Now, that's not to say that every single bit of code using "template <T> class Base : public T" always do things right, or that the author understood what it's doing. I haven't look at CExpatImpl, so I can't speak to its use. But if you use the technique correctly, it's a good thing, IMO.

-- DanielBowen?

[1] <http://archive.devx.com/free/mgznarch/vcdj/1999/julmag99/atlinherit1.asp>


Although the ActivexTemplateLibrary? list used to debate whether JimCoplien was the first in print, Coplien himself attributes the [CuriouslyRecurringTemplate] pattern to others. The article Igor mentioned is reproduced in C++ Gems (ISBN 0135705819 ) -- TimTabor?


I must say that the non-traditional inheritance (DynamicBinding) has allowed us to create a really cool skinning engine at our company. We take full advantage of the dynamic binding to create our skinned UI and our lower-level classes. We couldn't have done what we have done in WTL with MicrosoftFoundationClasses or without DynamicBinding. -- ScottAndrew?


Gee, why do a lot of porn queries redirect to this topic? :-)


CategoryCpp CategoryCppTemplates


EditText of this page (last edited January 2, 2013) or FindPage with title or text search