PDA

View Full Version : Virtual destructors



jml
14th January 2008, 19:38
This is an issue that has been bugging me for some time since starting to use Qt. Why do so many of the classes not have virtual destructors, since it seems clear that they may be used as base classes for derived classes?

An obvious example is QWidget. Clearly this is a base class for many other classes, but according the documentation, the destructor is not virtual. My understanding has always been is that if a class can be a base class for other classes, the destructor should always be virtual. Is there some essential gap in my knowledge of C++ programming (surely not!:eek:)?

Thanks for any input.

jacek
14th January 2008, 19:44
QWidget is derived from QObject which has a virtual destructor and once something has been declared virtual, it stays virtual.

jml
14th January 2008, 20:00
That begs the question as to why some classes, such as QTextEdit, do have virutual destructors.


Example:



class Foo
{
public:
Foo()
virtual ~Foo();
};
class Bar : public Foo
{
public:
Bar();
~Bar();
};
class SubBar : public Bar
{
public:
SubBar()
~SubBar();
};

Foo *f1 = new Bar();
Bar *b1 = new subBar();


Now when b1 is deleted, Bar's destructor is invoked since Foo's destructor is virtual. However when b1 is deleted, SubBar's destructor is NOT invoked, since Bar's destructor is not virtual. This strikes me as a problem.

jacek
14th January 2008, 20:20
That begs the question as to why some classes, such as QTextEdit, do have virutual destructors.
All widgets do have a virtual destructor, because they inherit QObject which has a virtual destructor.

Gopala Krishna
14th January 2008, 20:25
That begs the question as to why some classes, such as QTextEdit, do have virutual destructors.


Example:



class Foo
{
public:
Foo()
virtual ~Foo();
};
class Bar : public Foo
{
public:
Bar();
~Bar();
};
class SubBar : public Bar
{
public:
SubBar()
~SubBar();
};

Foo *f1 = new Bar();
Bar *b1 = new subBar();


Now when b1 is deleted, Bar's destructor is invoked since Foo's destructor is virtual. However when b1 is deleted, SubBar's destructor is NOT invoked, since Bar's destructor is not virtual. This strikes me as a problem.

Did you try the example you gave here ? Just put some cout/qDebugs and you will be able to confirm that deleting b1 calls destructor of SubBar.
~Bar is virtual since it inherits Foo which has virtual destructor.

EDIT:
Just for your info

#include <iostream>
using namespace std;

class Foo
{
public:
Foo() { cout << "Foo" << endl; }
virtual ~Foo() { cout << "~Foo" << endl; }
};
class Bar : public Foo
{
public:
Bar() { cout << "Bar" << endl; }
~Bar() { cout << "~Bar" << endl; }
};
class SubBar : public Bar
{
public:
SubBar() { cout << "SubBar" << endl; }
~SubBar() { cout << "~SubBar" << endl; }
};

int main()
{
Foo *f1 = new Bar();
Bar *b1 = new SubBar();
delete b1;
return 0;
}


Output
Foo
Bar
Foo
Bar
SubBar
~SubBar
~Bar
~Foo

jml
14th January 2008, 20:48
Ugh! You're right. I did have a basic misunderstanding on how virtual destrutors work. :o

Thanks.

wysota
15th January 2008, 00:10
That begs the question as to why some classes, such as QTextEdit, do have virutual destructors.

Because different people write the code and some of them redeclare methods as virtual and others not.