HCL Interview Question
Software Engineer / DevelopersYou need to make the destructor Virtual in case of inheritance in perticularly in following case -
If someone will derive from your class(class BASE),
and if someone will say new Derived, where Derived is derived from your class(BASE),
and if someone will say delete p, where the actual object's type is Derived class but the pointer p's type is your class(BASE).
something like this-
BASE *p;
p = new Derived();
delete p;
The idea is, compiler can understand how much sz should delete for built in types (int, char etc) but whenever your deleting
userdefined types basically it calls destr for that obj.
In above case whenever your deleting dervd obj with base ptr refernce, u need to declare base destr as virtual destr to clean up resources allocated by derived classes (new Derived() ---- calls derived constructor) else it calls only base destr.
If a class may serve as a base class for others, its destructor should be virtual
class Base{
char *p;
Base() { p = new char [200]; }
~ Base () {delete [] p; }
//...
};
class Derived : public Base {
char *q;
Derived() { q = new char[300]; }
~Derived() { delete [] q; }
//...
};
void destroy (Base & b) { delete &b; }
int main()
{
Base *pb = new Derived(); //200 + 300 bytes have been allocated
//... meddle with pb
destroy (*pb); //Oops! Base’s destructor is called but not //Derived’s; memory leak.
//Were Base’s destructor virtual, the //correct destructor would be alled.
}
If a class may serve as a base class for others, its destructor should be virtual
class Base{
char *p;
Base() { p = new char [200]; }
~ Base () {delete [] p; }
//...
};
class Derived : public Base {
char *q;
Derived() { q = new char[300]; }
~Derived() { delete [] q; }
//...
};
void destroy (Base & b) { delete &b; }
int main()
{
Base *pb = new Derived(); //200 + 300 bytes have been allocated
//... meddle with pb
destroy (*pb); //Oops! Base’s destructor is called but not //Derived’s; memory leak.
//Were Base’s destructor virtual, the //correct destructor would be alled.
}
If a class may serve as a base class for others, its destructor should be virtual
class Base{
char *p;
Base() { p = new char [200]; }
~ Base () {delete [] p; }
//...
};
class Derived : public Base {
char *q;
Derived() { q = new char[300]; }
~Derived() { delete [] q; }
//...
};
void destroy (Base & b) { delete &b; }
int main()
{
Base *pb = new Derived(); //200 + 300 bytes have been allocated
//... meddle with pb
destroy (*pb); //Oops! Base’s destructor is called but not //Derived’s; memory leak.
//Were Base’s destructor virtual, the //correct destructor would be alled.
}
SO Now what will be calling sequece Dervid Dest then base destr or Base destr then derived destr
As mentioned, the need exists if objects will be tracked by use of pointers of the type of the base class.
- Thomas S November 03, 2006A pointer to a base class object is of the type of the base class, but can refer to derived classes as well.
When you use that pointer to destroy/delete an object derived from the base class, and the pointer is to a base class object, then the destructor for the base class is called.
That destructor only knows about the base object components variables and memory allocations. It doesn't know about special variables instantiated in derived classes, nor does it even know what the derived class is.
By declaring the destructor virtual, the compiler will require the derived class declare its own destructor, AND, the type of the object pointed to by the generic base class pointer will be determined at run time rather than at compile time.
Thus if a base class pointer is used to destroy an object, the execution environement then determines the true type of the dervived class and calls that destructure (whihc must still be responsible and clean up what it should), rather than the base class destructor (which cannot possibly clean up what it doesn't know about).
The use of virtual destructors is a strong help in preventing memory leaks from a program.