
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.