1.2. Why do we need “pure” virtual destructor in HelloWorld?

Hi guys,

It has been such a long time since I wrote my last entry on this blog. For the whole summer, I was being really busy with summer session classes and Dingo. Therefore, about two weeks ago, I planned on giving myself a break by traveling around New Jersey this week. However, the Irene storm is hitting the East of United States, including NJ… and yeah it sucks. I am just gonna stay inside my dorm room for this whole weekend…

That is quite enough of a long story. Now let’s get right into the business of a typical computer nerd. This morning I received a question from a reader of my blog wondering:

“Why does the destructor of the HelloWorld example in this gtkmm tutorial need to be a “pure” virtual method? (put it just for the obligation to provide common C++ish-style in my code?)”

The simple answer is: No it is not.

It is necessary to declare “pure” virtual destructor especially if you are going to grow your software further than just a HelloWorld example. Since this question is related to C++, I am going to use a typical C++ example to illustrate this.

1. First: Why do we need a virtual destructor?
Let’s take a look at our example. Here it is:

class Base {
  Base();
  ~Base();
}

class Derived : public Base {
  Derived();
  ~Derived(); //non-virtual destructor
};

int main(int argc, char* argv[]) {
  /* p is a pointer to a Base object. Since Derived 
   * inherits from Base, we can use p to point to 
   * Derived object.
   */
  Base* p = new Derived();


  /* Now try to delete the above instance of the 
   * Derived class via p...
   */
  delete p; 
  /* ...which causes memory leak. The underlying
   * object is not destroyed. "delete" calls the 
   * Base::~Base() destructor, not the 
   * Derived::~Derived() destructor. But the 
   * underlying object's type is Derived, not Base!!
   */
}

In the above example, the problem occurs when we try to delete pointer p inside the main() function. When deleting p, what we really want to remove is the underlying Derived object. However, since the destructor Derived::~Derived() is non-virtual, the delete statement instead calls Derived‘s base class destructor, which is Base::~Base(). Therefore, the object that p points to (which is a Derived object) was not destroyed and this causes a memory leak.

Declaring a derived class destructor as virtual method is really important. In object-oriented software development, any user of your class (lots of time including yourself) will mostly have a pointer to an interface (Base), not a pointer to the concrete implementation (Derived). When they try to delete that pointer (p), if the destructor is non-virtual, the program will call the interface’s destructor (Base::~Base()) and not the derived class’s destructor (Derived::~Derived()). Therefore, the object you want to delete still exists and causes a memory leak.

2. Second: Why do we need “pure” virtual destructor in HelloWorld?
The answer to this question is simple: For now HelloWorld::~HelloWorld() is an empty destructor. However, as your software grows, you will need to destroy lots of widgets & pointers & objects as you exit the program. Therefore, to ensure consistency throughout the tutorial and also give you chance to practice a good gtkmm habit, I just define a “pure” virtual destructor (HelloWorld::~HelloWorld()) for my HelloWorld example. You will get used to it believe me!

Advertisements

2 Responses to “1.2. Why do we need “pure” virtual destructor in HelloWorld?”

  1. formwach Says:

    today, at mornig as i drink my tee
    and gonna miss my coffee,
    make a warm up typing in my console window
    first i get asdfljdfiuowerowi – monkey like,
    or a man, who has time to waste,
    learning stuff like coding, and want to break with it every
    day, stamp in the ground new kingdom of man,

    and then : apt-cache search gtkmm
    there a “newer” package
    released by the gtkmm development team
    in the version gtkmm-3.0-dev, -hold eyes wide open,
    does my hello wold code comes in ages ?

    • Phong Cao Says:

      Oh yeah gtkmm-3.0 was released several months ago or so. There are some minor changes but v3.0 was not much different from v2.4. Have a look at this page for more information about the changes. All of the codes in my blog are still valid with the new gtkmm-3.0 standard. You just have to change the gtkmm library name in your compile command from gtkmm-2.4 to gtkmm-3.0 if you want to compile the source with gtkmm-3.0. My new tutorial released this December will probably target gtkmm-3.0/gtk-3.0… Thank you anyway for mentioning…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: