Exploring Virtual Destructors in C++/CLI

This article discusses what virtual methods are, why constructors cannot be virtual and why virtual destructors are needed and the pitfalls if destructors are not defined virtual in some scenarios. The concepts are discussed in a lucid language with plenty of code examples to illustrate the concepts.

A constructor is a method that has the same name as the name of the class and is invoked at the time the class is instantiated. On the contrary, a destructor is a method that has the same name as the class name but is prefixed with a tilde sign.

Here is an example that illustrates how a constructor and a destructor look.

class Test
{
Test()
{
}
~Test()
{
}
};

Note that in C++ you cannot have access modifiers for constructors. Constructors in C++ cannot be non-static also.

Virtual Methods

Now, what is a virtual method? Well, the virtual keyword is prefixed to a method of a class to signify that the method is virtual. A virtual method is used to implement run-time polymorphism.

We now have a virtual method for the class Test shown below.

class Test
{
Test()
{
}
virtual int Sample()
{
//Some code
}
~Test()
{
}
};

Note that for classes that have virtual methods, you would have a virtual table in memory. Virtual tables are used to map the virtual methods at runtime. If a class has n virtual methods, there would be one and only one virtual table in memory where the mapping information of all the n virtual methods would be defined. Virtual tables are created at the time the constructor of the class is invoked. So, you cannot have a virtual constructor as at the time the constructor is invoked, virtual table for the class is not available in memory.

When you have a virtual method defined in a class, you have a virtual pointer made available to you that points to the base address of the virtual table in memory. Consider the following code.

class Base
{
public:
virtual void Sample()
{
printf("Hello from Base");
}
};
class Derived: public Base
{
public:
virtual void Sample()
{
printf("Hello from Derived");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Base *b = new Derived;
b->Sample();
getchar();
return 0;
}

When you execute the above code, the message “Hello from Derived” is displayed on the screen. Now, if you omit the virtual keyword from each of the classes, i.e., the Base and also the Derived classes, you would see that the message “Hello from Base” is displayed.

class Base
{
public:
void Sample()
{
printf("Hello from Base");
}
};
class Derived: public Base
{
public:
void Sample()
{
printf("Hello from Derived");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Base *b = new Derived;
b->Sample();
getchar();
return 0;
}

The reason is that when a base class pointer points to a derived class instance and a method on the instance is called, the base version would always be invoked as the type of the pointer would be considered. However, if the method is defined as virtual in both the base and the derived classes, the context of the pointer would be considered. Hence the result.

Why do we Need Virtual Destructors?

A destructor can be virtual. Why should a destructor be virtual? Let’s consider a scenario in which there are two classes, a base class called Base and a derived class called Derived. Now, constructors are invoked in the order of inheritance and destructors are invoked in the reverse order of inheritance. So, in this example, the constructor of the Base class would be invoked followed by the Derived class constructor. So, the Derived class destructor would be invoked followed by the Base class destructor at the time when the object goes out of the scope or is destroyed.

Now, suppose you create an instance of the Derived class using a Base class pointer as we did earlier in this article. When you delete the pointer object using the delete keyword, the destructor of the Base class would be called and the destructor of the Derived class would simply be ignored.

The reason is that the destructor is simply another method and so when the delete keyword is used to delete the pointer instance, the type of the pointer would be considered. And, because the type of the pointer is of type Base, the destructor of the Base class would only be invoked. This might create memory leaks as the instance of the derived class would still remain in memory even after the pointer instance has been deleted/destroyed from memory. To avoid this potential memory leak, virtual destructors are used.

Summary

Virtual destructors in C++ are used to avoid memory leaks when your class contains unmanaged code, i.e., contains pointers or object handles to files, databases or other external objects. In this article we explored virtual methods and virtual destructors in C++. Happy reading!

About the Author

Joydip Kanjilal is a Microsoft Most Valuable Professional in ASP.NET, speaker and author of several books and articles. He has over 16 years of industry experience in IT with more than 10 years in Microsoft .NET and its related technologies. Joydip was selected as MSDN Featured Developer of the Fortnight (MSDN) a number of times and also as Community Credit Winner. His books include the Entity Framework Tutorial, Sams Teach Yourself ASP.NET Ajax in 24 Hour, and ASP.NET Data Presentation Controls Essentials. You can follow him on Twitter (@joydipkanjilal) or see more about him on LinkedIn at http://in.linkedin.com/in/joydipkanjilal

Joydip Kanjilal
Joydip Kanjilal
A Microsoft Most Valuable Professional in ASP.NET, Speaker, and Author of several books and articles. More than 25 years of experience in IT with more than 18 years in Microsoft .NET and its related technologies. He was selected as a Community Credit Winner at http://www.community-credit.com several times. He has authored 8 books and more than 500 articles in some of the most reputed sites worldwide including MSDN, Info World, CodeMag, Tech Beacon, Tech Target, Developer, CodeGuru, and more.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read