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

Base  class  destructors  should  always  be  virtual.  Suppose  you  use  delete  with  a  base class  pointer  to  a  derived  class  object  to  destroy  the  derived - class  object.  If  the base class  destructor  is  not  virtual,  then  delete,  like  a  normal  member  function,  calls the destructor  for  the  base  class,  not  the  destructor  for  the  derived  class.  This  will cause only  the  base  part  of  the  object  to  be  destroyed.


                                   class  B
                                   {
                                               public :
                                                           ~ B ( )
                                                            {
                                                                   cout  <<  " base  destroyed " ;
                                                            }
                                   } ;

                                   class  D : public  B
                                   {
                                             public :
                                                            ~D ( )
                                                            {
                                                                   cout  <<  " derived  destroyed " ;
                                                            }
                                   } ;

                                   int  main ( )
                                   {
                                              B  * ptr = new  D ;
                                              delete  ptr ;
                                              return  0 ;
                                   }


The  output  from  this  program  is

base  destroyed


This  shows  that  the  destructor  for  the  D  part  of  the  object  isn't  called.  The  reason  is base  class  destructor  is  not  virtual.  If  you  make  base  class  destructor  virtual  then  both parts  of  the  derived  class  object  are  destroyed  properly.


                                                                      virtual ~ B ( )
                                                                      {
                                                                              cout  <<  " Base  destroyed " ;
                                                                      }



Now  output  from  this  program  is

derived  destroyed
base  destroyed


virtual  Constructors

C++  does  not  provide  virtual  constructors  because  a  constructor  needs  the  information about  the  exact  type  of  the  object  it  is  creating  to  construct  it  correctly.  However, situations  occur  when  a  pointer  to  a  base  class  is  available,  and  the  program  needs a copy  of  the  actual  derived  class  that  the  pointer  is  referencing.


For  example,  
                                                          class  Derived ;

                                                          class  Base
                                                           {
                                                                 public :
                                                                                   Base ( ) ;
                                                                                   Base ( const  Base & ) ;
                                                                                   Base ( const  Derived & ) ;
                                                                                   // . . . .
                                                           } ;

                                                           class  Derived : public  Base
                                                           {
                                                                   public :
                                                                                Derived ( ) ;
                                                           } ;

                                                           int  main ( )
                                                           {

                                                                       Base  *p1 = new  Derived ;

                                                                       Base  *p2 = new  Base (  *p1 ) ;

                                                                       // . . . .
                                                           }


The  initialization  of  p2  invokes  

Base : : Base ( const  Base & ) ;

and,  not  the  following  constructor

Base  : :  Base ( const  Derived & ) ;

Such  a  thing  would  have  been  possible  with  the  help  of  a  virtual  constructor.

C++,  however,  does  provide  features  that  let  programmer  simulate  the  effect  of  a virtual constructor:



                                                           class  Derived ;
                             
                                                           class  Base
                                                           {
                                                                       public :
                                                                                   Base ( ) ;
                                                                                   Base ( const  Base & ) ;
                                                                                   Base ( const  Derived & ) ;
                                                                                   virtual  Base *  Instance ( )
                                                                                   {
                                                                                           return  new  Base ( ) ;
                                                                                   }
                                                                                   
                                                                                   // . . . .
                                                           } ;

                                                           class  Derived : public  Base
                                                           {
                                                                        public :
                                                                                   Derived ( ) ;
                                                                                   Derived ( const  Derived & ) ;
                                                                                   virtual  Derived *  Instance ( )
                                                                                   {
                                                                                               return  new  Derived ( ) ;
                                                                                   }
                                                           } ;

                                                           int  main ( )
                                                           {
                                   
                                                                       Base  *p1 = new  Base ;

                                                                       Base  *p2 = new  Derived ;

                                                                       Base  *p3 = p1->Instance ( ) ;

                                                                       Base  *p4 = p2->Instance ( ) ;

                                                                       // . . . .
                                                           }


The  virtual  function  Instance ( )  simply  returns  a  default  initialized  instance  of  the  class allocated  on  the  free  store.  Thus,  in  the  above  example,  p3  points  to  an  instance  of the class  Base,  and  p4  points  to  an  instance  of  the  class  Derived.