locked
Question about Template Idiom RRS feed

  • Question

  • I'm hoping someone can explain a C++ template idiom to me.
     
    In WTL, there are many classes that perform tasks that I would normally
    implement using virtual functions. Example of how I would do it:
     
    class CButtonImpl
    {
    virtual LRESULT OnPaint( WPARAM wParam... )
    {
    // Do stuff.
    return 0;
    }
    }
     
    However, the WTL idiom is to use a template class and static cast:
     
    template <class T>
    class CButtomImpl : public CWindowImpl<T>
    {
    LRESULT OnPaint( WPARAM wParam ... )
    {
    T* pT = static_cast<T*>(this);
    pT->DoPaint((HDC)wParam);
    return 0;
    }
    }
     
    Why? What do I gain by using this idiom?
    --
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.
     

    Tim Roberts, DDK MVP
    Friday, July 9, 2010 4:56 AM

Answers

  • It basically will do the same thing as when you use a virtual function.

    I advantage here is that there is no virtual function tables that need to be generated.

    And the method will be statically linked rather than dynamic linking as when using virtual function.

     

    So in effect you have a smaller footprint.

    This is especially true when you have a huge hierarchy tree like MFC.

     

    And you have faster running code because when you use virtual tables, the compiler generates special code to call you're functions using function pointer in the virtual tables.

    In this case the method binding happens to the correct method at compile time.

     


    «_Superman_»
    Microsoft MVP (Visual C++)
    • Proposed as answer by ildjarn Friday, July 9, 2010 9:04 AM
    • Marked as answer by Kira Qian Monday, July 19, 2010 9:01 AM
    Friday, July 9, 2010 5:49 AM

All replies

  • It basically will do the same thing as when you use a virtual function.

    I advantage here is that there is no virtual function tables that need to be generated.

    And the method will be statically linked rather than dynamic linking as when using virtual function.

     

    So in effect you have a smaller footprint.

    This is especially true when you have a huge hierarchy tree like MFC.

     

    And you have faster running code because when you use virtual tables, the compiler generates special code to call you're functions using function pointer in the virtual tables.

    In this case the method binding happens to the correct method at compile time.

     


    «_Superman_»
    Microsoft MVP (Visual C++)
    • Proposed as answer by ildjarn Friday, July 9, 2010 9:04 AM
    • Marked as answer by Kira Qian Monday, July 19, 2010 9:01 AM
    Friday, July 9, 2010 5:49 AM
  • Note that this idiom is formally known as a mixin class (that happens to use CRTP).
    Friday, July 9, 2010 9:05 AM
  • Tim: it is well explained in the paragraph "ATL-style templates" of part 1 of great Michael Dunn's series on WTL on CodeProject.

    Giovanni

     

    Friday, July 9, 2010 10:20 AM
  • «_Superman_» [MVP] wrote:
    >
    >It basically will do the same thing as when you use a virtual function.
    >
    >I advantage here is that there is no virtual function tables that need
    >to be generated.
    >
    >And the method will be statically linked rather than dynamic linking
    >as when using virtual function.
     
    I see. The tradeoff, then, is that the inheritance tree can only be one
    level deep. And, in the real world, trees don't usually go very deep.
     
    >This is especially true when you have a huge hierarchy tree like MFC.
     
    Where "huge" refers to a wide, but very shallow tree.
    --
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.
     

    Tim Roberts, DDK MVP
    Saturday, July 10, 2010 7:29 PM
  • This pattern doesn't change the logical depth of an inheritance tree, it just changes the dispatch mechanism. The WTL control classes are a perfect example of this, actually.
    Saturday, July 10, 2010 7:44 PM
  • Tim Roberts [MVP] wrote:

    «_Superman_» [MVP] wrote:


    It basically will do the same thing as when you use a virtual  function.

    I advantage here is that there is no virtual function tables that  need
    to be generated.

    And the method will be statically linked rather than dynamic linking
    as when using virtual function.

    I see. The tradeoff, then, is that the inheritance tree can only be  one
    level deep.

    Not necessarily:

    template <typename T>
    class Mixin {};

    template <typename T>
    class DerivedMixin : public Mixin<T> {};

    class MyClass : public DerivedMixin<MyClass> {};

    This is especially true when you have a huge hierarchy tree like MFC.

    Where "huge" refers to a wide, but very shallow tree.

    We might have a different definition of "very shallow". E.g., your  typical ActiveX control is derived from COleControl, derived from CWnd,  derived from CCmdTarget, derived from CObject. If that's very shallow, I  wonder what a deep hierarchy looks like.


    Igor Tandetnik

    Saturday, July 10, 2010 7:44 PM