EverSpring working shop

To pursue creative ideas based on nature.

统计

留言簿(1)

他山之石

阅读排行榜

评论排行榜

Some notes about dynamic polymorphism (by virtual) and static polymorphism (by template)

The time and space cost by the late binding (dynamic polymorphism), which is mainly implemented by Virtual Functions, is more than the static polymorphism, mainly implemented by the Template usage. This is because the compiler needs to allocate speical VPTR and VTABLE for each class with virtual function denoted. And duirng the compiling time, the original code is expanded by adding the code locating the virtual functiona address in the VTABLE, at each place the base class pointer/reference are passed as parameter in other function call. Finally, at the running time, such extra code absolutely costs extra time, especially when the base class pointer/referece are passed as parms very frequently.  We can consider to use the template in such sitations like:
    • The context is using the Set of the objects instead of the pointer/reference, and the objects of this set have common behavior at a level of abstraction. The typical application is the Containers design in the STL.
    • The algorithem or behavior of different objects has some common attribute and this common attributes can be determined at compiling time.
    • Policy based programming, and such policy selection can be determined by the client at the compiling time. Refer to MCppD.
    • Very senstive to the requirements on efficiency of time or space.
Must be noted: The bahavior must be determined at the compiling time if using the Template Polymorphism. This means the the client must have the type information explicitly during the code construction time. From this point, we may say the in Template Polymorphism, the CLIENT is the usually in design scope of application because it is responsible for the Template Specialization. As to the Dynamic, the CLIENT is more in the design scope for the framework, not care of the concrete type information in operation.
Here give an example explaining the usage of the dynamic/static polymorphism:
 
#include <iostream>
using namespace std;
 

/*
 * =====================================================================================
 *        Class:  base_d
 *  Description: 
 * =====================================================================================
 */
class base_d
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    base_d ();  /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
    virtual void dosomething() = 0;
    /* ====================  ACCESS      ========================================= */
 
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
 
}; /* -----  end of class  base_d  ----- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  base_d
 *      Method:  base_d
 * Description:  constructor
 *--------------------------------------------------------------------------------------
 */
base_d::base_d ()
{
}  /* -----  end of method base_d::base_d  (constructor)  ----- */
 

/*
 * =====================================================================================
 *        Class:  client_d
 *  Description: 
 * =====================================================================================
 */
class client_d
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    client_d (base_d*);  /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
 
    /* ====================  ACCESS      ========================================= */
    void get_do();
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
    base_d* ptr_b;
 
}; /* -----  end of class  client_d  ----- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  client_d
 *      Method:  client_d
 * Description:  constructor
 *--------------------------------------------------------------------------------------
 */
client_d::client_d (base_d* pb):ptr_b(pb)
{
}  /* -----  end of method client_d::client_d  (constructor)  ----- */
 

void
client_d::get_do (  )
{
 ptr_b->dosomething();
}  /* -----  end of method client_d::get_do  ----- */
 

/*
 * =====================================================================================
 *        Class:  der1_d
 *  Description: 
 * =====================================================================================
 */
class der1_d : public base_d
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    der1_d ();  /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
    virtual void dosomething();
    /* ====================  ACCESS      ========================================= */
 
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
 
}; /* -----  end of class  der1_d  ----- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  der1_d
 *      Method:  der1_d
 * Description:  constructor
 *--------------------------------------------------------------------------------------
 */
der1_d::der1_d ()
{
}  /* -----  end of method der1_d::der1_d  (constructor)  ----- */
 

void
der1_d::dosomething (  )
{
    cout <<"\n this is der1_d is doing something!\n";
}  /* -----  end of method der1_d::dosoming  ----- */
 

/*
 * =====================================================================================
 *        Class:  der2_d
 *  Description: 
 * =====================================================================================
 */
class der2_d : public base_d
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    der2_d ();  /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
    virtual void dosomething();
    /* ====================  ACCESS      ========================================= */
 
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
 
}; /* -----  end of class  der2_d  ----- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  der2_d
 *      Method:  der2_d
 * Description:  constructor
 *--------------------------------------------------------------------------------------
 */
der2_d::der2_d ()
{
}  /* -----  end of method der2_d::der2_d  (constructor)  ----- */
 

void
der2_d::dosomething (  )
{
    cout <<"\n this is der2_d is doing something!\n";
}  /* -----  end of method der2_d::dosomething  ----- */
 

/*
 * =====================================================================================
 *        Class:  client_s
 *  Description: 
 * =====================================================================================
 */
template < class T >
class client_s
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    client_s (T* );   /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
    void get_do();
    /* ====================  ACCESS      ========================================= */
 
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
    T* ptr_t;
}; /* ----------  end of template class  client_s  ---------- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  client_s
 *      Method:  client_s
 * Description: 
 *--------------------------------------------------------------------------------------
 */
template < class T >
client_s < T >::client_s (T* pt):ptr_t(pt)
{
}  /* ----------  end of constructor of template class client_s  ---------- */
 
template < class T>
void
client_s<T>::get_do (  )
{
 ptr_t->dosomething();
}  /* -----  end of method client_s::get_do  ----- */
 

/*
 * =====================================================================================
 *        Class:  der1_s
 *  Description: 
 * =====================================================================================
 */
class der1_s
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    der1_s ();  /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
    void dosomething();
    /* ====================  ACCESS      ========================================= */
 
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
 
}; /* -----  end of class  der1_s  ----- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  der1_s
 *      Method:  der1_s
 * Description:  constructor
 *--------------------------------------------------------------------------------------
 */
der1_s::der1_s ()
{
}  /* -----  end of method der1_s::der1_s  (constructor)  ----- */
 

void
der1_s::dosomething (  )
{
    cout <<"\n this is der1_s doing something!\n" ;
}  /* -----  end of method der1_s::dosomething  ----- */
 

/*
 * =====================================================================================
 *        Class:  der2_s
 *  Description: 
 * =====================================================================================
 */
class der2_s
{
 
  public:
 
    /* ====================  LIFECYCLE   ========================================= */
 
    der2_s ();  /* constructor */
 
    /* Use compiler-generated copy constructor, assignment operator and destructor */
 
    /* ====================  OPERATORS   ========================================= */
 
    /* ====================  OPERATIONS  ========================================= */
    void dosomething();
    /* ====================  ACCESS      ========================================= */
 
    /* ====================  INQUIRY     ========================================= */
 
  protected:
 
  private:
 
}; /* -----  end of class  der2_s  ----- */
 
/*
 *--------------------------------------------------------------------------------------
 *       Class:  der2_s
 *      Method:  der2_s
 * Description:  constructor
 *--------------------------------------------------------------------------------------
 */
der2_s::der2_s ()
{
}  /* -----  end of method der2_s::der2_s  (constructor)  ----- */
 

void
der2_s::dosomething (  )
{
 cout<<"\n this is der2_s doing something!\n" ;
}  /* -----  end of method der2_s::dosomething  ----- */
 

int main()
{
   // Dynamic Polymorphism example:
   base_d * ptr_1 = new der1_d;
   base_d * ptr_2 = new der2_d;
 
   client_d * ptr_c_1 = new client_d(ptr_1);
   client_d * ptr_c_2 = new client_d(ptr_2);
 
   ptr_c_1 -> get_do();
   ptr_c_2 -> get_do();
 
   // Static Polymorphism example:
   der1_s * ptr_3 = new der1_s;
   der2_s * ptr_4 = new der2_s;
  
   client_s<der1_s> obj_client_1(ptr_3);
   client_s<der2_s> obj_client_2(ptr_4);
 
   obj_client_1.get_do();
   obj_client_2.get_do();
 
   return 0;
}
testing out:
[alexzh@alexzhang_lnx d_s_poly]$ ./a.out
 
 this is der1_d is doing something!
 
 this is der2_d is doing something!
 
 this is der1_s doing something!
 
 this is der2_s doing something!

posted on 2009-03-08 17:25 everspring79 阅读(359) 评论(0)  编辑 收藏 引用 所属分类: Notes


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理