PDA

View Full Version : Confused - QGraphicsItem destructor



durbrak
11th February 2008, 18:44
Hi guys,

I'm sort of confused right now. Let's say I have created a QGraphicsLineItem(), which will eventually have children (all sorts of graphics items, doesn't really matter). Now I want to explicitly delete my object:

QGraphicsLineItem *line = new QGraphicsLineItem(scene);
//...
QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(line);
//...
delete line;
line = 0;

Now the part I don't get is that in the Qt sources the destructor of QGraphicsLineItem is empty:

QGraphicsLineItem::~QGraphicsLineItem()
{
}

QGraphicsLineItem is, of course, a sub-class of QGraphicsItem, which has the destructor defined with code to delete all its children.
So, how is it, that if I delete my QGraphicsLineItem that it will also delete all its children (i.e. *label)? The base class destructor QGraphicsItem::~QGraphicsItem() is declared as virtual, thus a destructor wouldn't be needed for QGraphicsLineItem, right? And by declaring an own destructor for QGraphicsLineItem which is empty, the base class destructor doesn't get called, right?

Or am I missing something here?
Thanks.

jpn
11th February 2008, 18:51
And by declaring an own destructor for QGraphicsLineItem which is empty, the base class destructor doesn't get called, right?
Well actually, the base class destructor gets called right after sub class destructor.

durbrak
11th February 2008, 18:58
So, it's a feature of C++ to call every single destructor from the sub-class up to the base-class?
And why is a destructor for QGraphicsLineItem() defined? Wouldn't the base-class destructor be called if there was no destructor in the sub-class?

jpn
11th February 2008, 19:17
So, it's a feature of C++ to call every single destructor from the sub-class up to the base-class?
Yup. That's the reverse order of constructors. Notice that even if you don't explicitly call a base class constructor the default one gets called.


And why is a destructor for QGraphicsLineItem() defined?
Some C++ programmers tend to define destructors even if they're empty. This makes it clear that the destructor wasn't simply forgotten. Usually you need destructors in C++ more often than what you need when working with Qt, thanks to certain automatic cleanups.


Wouldn't the base-class destructor be called if there was no destructor in the sub-class?
Yeah, it would.

Gopala Krishna
11th February 2008, 20:02
And why is a destructor for QGraphicsLineItem() defined?

I feel they do this also so that they can do additional cleanups later without breaking binary compatibility

jpn
11th February 2008, 20:31
I feel they do this also so that they can do additional cleanups later without breaking binary compatibility
Introducing a new function in class interface does not break ABI. Thus, you can later add a destructor if needed. But once added you can't later remove it. So I'd say the opposite; perhaps there was earlier something to cleanup. :)

Gopala Krishna
12th February 2008, 12:43
Oh ya no ? I got it wrong.
Thanks for correcting me :)

Bitto
13th February 2008, 20:27
Adding a reimplementation of a virtual function doesn't break BC, but it also doesn't take effect until the source is recompiled. So if you need to fix a bug by adding functionality in a reimplementation, you're not actually fixing existing apps. By defining the function from the start, we know that the destructor is called by the application already, so we can safely add code and rely on it being called. Otoh, if we add a reimplementation, existing compilation units will still call the "old" implementation; they won't call the new implementation until the app is recompiled.

Because of that, it's best for a library to always reimplement virtual functions in subclasses, even if the implementation is an empty destructor, or if it just calls the base implementation. (Note though that not all classes in Qt do this).