Learning  C++
Home
Tutorials
C++  Programs
Contact  us
Sitemap
Your Ad Here
Your Ad Here
Virtual  Functions

A  virtual  member  function  is  a  special  member  function  invoked  through  a  public  base class reference  or  pointer.  It  is  bound  dynamically  at  run time.  The  instance  invoked  is determined by  the  class  type  of  the  actual  object  addressed  by  the  pointer  or reference.  

A  virtual  function  is  declared  by  prefacing  a  member  function  declaration  with  C++ keyword virtual.

The  virtual  function  mechanism  allows  derived  classes  to  provide  different  versions  of  a base class  function.  Programmer  declares  a  virtual  function  in  a  base  class,  then  redefines it in any derived  class.  A  redefined  virtual  function  is  said  to  override  the base class  function.

When  programmer  declares  a  virtual  function,  she  must  keep  these  guidelines  in  mind:

1)  A  virtual  function  can  only  be  a  member  function.

2)  It  can  be  declared  a  friend  in  another  class.

3)  It  cannot  be  a  static  member,  since  its  call  depends  on  a  specific  object            
for  determining  which  version  of  the  function  to  invoke.

4)  They  are  accessed  by  using  object  pointers.  

Example :

                                   class  Base
                                   {
                                            public :
                                                     virtual  void  show ( )
                                                     {
                                                            cout  <<  "base n" ;
                                                     }
                                   } ;


                                   class  Derived1  :  public  Base
                                   {
                                            public :
                                                   void  show ( )
                                                   {
                                                          cout  <<  "derived1  n" ;
                                                   }
                                   } ;


                                   class  Derived2  :  public  Base
                                   {
                                            public :
                                                     void  show ( )
                                                     {
                                                            cout  <<  "derived2  n" ;
                                                      }
                                   } ;


                                       int  main ( )
                                       {

                                                 Base  b1 ;
                                                 Derived1  d1 ;
                                                 Derived1  d2 ;
                                                 Base *  ptr ;

                                                 ptr = & b1 ;
                                                 ptr->show ( ) ;  //  execute  Base  show ( )

                                                 ptr = & d1 ;
                                                 ptr->show ( ) ;  //  execute  Derived1  show ( )

                                                 ptr = & d2 ;
                                                 ptr->show ( ) ;  //  execute  Derived2  show ( )

                                                 return  0;

                                       }


The  output  of  this  program  is:
base
derived1
derived2


This  is  an  amazing  capability:  Completely  different  functions  are  executed  by  the  same function  call.


virtual  Tables

In  order  to  implement  dynamic  binding,  the  compiler  has  to  go  through  some  extra  steps whenever  there  is  atleast  one  virtual  function  within  a  class.  First  it  creates  a  table  called the  virtual  function  table,  usually  referred  to  as  the  ' vtbl '.  This  table  contains  the  addresses of  all  of  the  virtual  functions  within  the  class.  The  first  address  occupies position  0,  the next position  1,  etc.  For  each  derived  class,  the  table  is  duplicated,  and  if  a  virtual function  is redefined,  then  its  address  replaces  the  address  of  the  corresponding  function from  the base  class.  Any  new  virtual  functions  are  appended  to  the  end  of  the  table.

Whenever  an  instance  of  a  class  is  created,  the  compiler  reserves  some  extra  bytes  for use  as  a  pointer  to  the  ' vtbl '.  This  pointer  is  referred  to  as  the  ' vptr '  or  virtual  pointer.  It is  automatically  initialized  to  point  to  the  ' vtbl '  for  the  class  to  which  it  belongs.  When  you create  a  pointer  of  type  base  and  store  into  it  the  address  of  a  base  or  derived  instance, and  then  execute  a  function  using  this  pointer,  the  compiler  will fetch  the  address  pointed at by  ' vptr '  of  the  invoking  instance  ( * this ),  offset  this  address  by  the  index  of  the function in question  ( 0  for  f ( ) ,  1  for  g ( ) ) ,  fetch  the  address  from the  ' vtbl '  and  execute  the function that  this  address  points  at.