CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15

Threaded View

  1. #1
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    template design question

    Hi,

    I´m messing around with the borland VCL and have to accomplish the following task: There are many types (like TStaticText, TLabel, TEdit ...) that have properties with the same name, but unfortunately there´s no common base class with these properties made public, so I can´t use
    Code:
    ((TWinControl *) pObject)->Text = "Hello World";
    Example:
    Code:
    class TWinControl 
    {
       protected:
         AnsiString  Caption;
    ...
    };
    
    class TLabel : public TWinControl
    {
       public :
         AnsiString Caption;
    ...
    };
    
    class TStaticText : public TWinControl
    {
       public:
         AnsiString Caption;
    };
    I read component properties (text color, font style, etc.) from a file and have to assign these properties to different control types. My current naive approach is providing a function for each control type and perform customization inside that function:

    Code:
    void CustomizeLabel( TLabel *pLabel, TComponentProperties *pProps )
    {
        pLabel->Text = pProps->Text;
       pLabel->Color = pProps->Color;
       ...
    }
    
    void CustomizeMenu( TMenu *pMenu, TComponentProperties *pProps )
    {
    ...
    }
    
    void CustomizeButton( TButton *pButton, TComponentProperties *pProps )
    {
    ...
    }
    My second approach is to use templates and traits to handle different control types:

    Code:
    template<class TTarget> TNoOp
    {
       TNoOp( TObject *pTarget, TComponentProperties *pProps )
       {
      }
    }
    
    
    template<class TTarget> TCaptionSetter
    {
       TCaptionSetter( TObject *pTarget, TComponentProperties *pProps )
       {
          ((TTarget *) pTarget)->Caption = pProps->Text;
      }
    }
    
    template<class TTarget> TColorSetter
    {
       TColorSetter( TObject *pTarget, TComponentProperties *pProps )
       {
          ((TTarget *) pTarget)->Color = pProps->Color;
      }
    
    
    template<class TTarget, class TTextHandler, class TColorHandler> class TCustomizer
    {
       TCustomizer( TObject *pTarget, TComponentProperties *pProps )
       {
          TTextHandler( pTarget, pProps );
          TColorHandler( pTarget, pProps );
       }
    }
    Now I can use the following constructs to assign text and/or color:

    Code:
    // set caption and color
    TCustomizer<TLabel, TCaptionSetter<TLabel>, TColorSetter<TLabel> Cust( pObj, pProps );
    
    // set caption only, ignore color
    TCustomizer<TMenu, TCaptionSetter<TMenu>, TNoOp<TMenu> Cust( pObj, pProps );
    Using the code above I have to specify the type name for each of the traits, making the code less readable. The type names are redundant, because they´re already known by the class TCustomizer, so I want to get rid of the template spec for the traits. I´m quite new to templates and generic programming, is it possible to create a construct without specialized trait classes? Like
    Code:
    template<class TTarget, class TCaptionSetter, class TColorSetter> TCustomizer
    {
       TCustomizer( TObject *pObj, TComponentProperties *pProps )
       {
          TCaptionSetter ts( pObj, pProps );
          TColorSetter     cs( pObj, pProps );
       }
    }
    I want to use the template this way:
    Code:
    TCustomizer<TLabel, TCaptionSetter, TNoOp> Cust( pObj, pProps );

    Third approach (just coming in mind, I don´t know if it will work):

    Code:
    template<class TTarget, class TTextHandler, class TColorHandler> class TCustomizer
    {
      TTarget                          *m_pTarget;
       TComponentProperties *m_pProps;
    
       class TColorSetter( TCustomizer<TTarget> *pCustom )
       {
          pCustom->Target->Color = pCustom->m_Props->Color;
       }
    
       class TCaptionSetter( TCustomizer<TTarget> *pCusom )
       {
          pCustom->Target->Caption = pCustom->m_Props->Text;
       }
    
       TCustomizer( TObject *pTarget, TComponentProperties *pProps )
       {
           m_pTarget = (TTarget *) pTarget;
           m_pProps  = pProps;
    
          TTextHandler th( this );
          TColorHandler tc( this );
       }
    }
    Can I use
    Code:
    TCustomizer<TLabel, TCustomizer::TTextSetter,TCustomizer::TColorSetter> Cust( pObj, pProps );
    ?
    Edit: Third approach can´t work, please ignore.

    Thanks in advance,
    Guido
    Last edited by GNiewerth; November 21st, 2006 at 03:34 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured