[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: Problem with QT
From:       Bernd Brandstetter <bbrand () freenet ! de>
Date:       2005-10-22 8:59:29
Message-ID: 200510221100.57389.bbrand () freenet ! de
[Download RAW message or body]

On Saturday 22 October 2005 10:40, André Wöbbeking wrote:
> On Saturday 22 October 2005 09:27, Bernd Brandstetter wrote:
> > On Saturday 22 October 2005 00:46, David Faure wrote:
> > > > And for a perhaps more useful answer, add a destructor for
> > > > KgpgListKeys that iterates over its keys and deletes them.  You
> > > > might not be able to use foreach() since the dtor will be
> > > > iterating over itself but something like this would work:
> > > >
> > > > KgpgListKeys::~KgpgListKeys()
> > > > {
> > > >   for(ConstIterator it = constBegin(); it != constEnd(); ++it)
> > > >   {
> > > >     delete *it;
> > > >   }
> > >
> > > qDeleteAll(this) should do the same as the above code.
> >
> > But be very careful when putting this in the destructor. If somebody
> > iterates this list using foreach(), he will end up with all elements
> > being deleted after the loop - which is most probably not what he
> > expected.
>
> ???
>
> If an object (in the case the the list) was destructed you MUST NOT use
> it anymore.

No, I meant something different:
Say you have derived a _pointer-based_ list from QList

class MyList : public QList<SomeClass*>
{
    ...
}

and since you always want all list items to be deleted along with the list, 
you put qDeleteAll(this) in the destructor of the class to simulate the 
behavior of Qt3's setAutoDelete()

MyList::~MyList()
{
    qDeleteAll(this);
}

Now, if you happen to iterate over such a list using foreach() like this

MyList list;
// fill list with items

foreach(SomeClass* item, list)
{
    // do something with the item
}

then at this point after the foreach loop has finished, the contents of the 
original list, i.e. the objects pointed to by the list items, have been 
deleted.

That's because foreach() creates a temporary copy of the list and iterates 
over that one. After the iteration, the temporary list is deleted, thereby 
calling the destructor defined above and thus, deleting all items!

This occured to me when I ported an application from Qt3 to Qt4 and it took 
me quite some time to find out why it kept crashing. Now my rule of thumb 
is: _Never_ call qDeleteAll(this) in the destructor of _pointer-based_ 
collections!

Regards,
Bernd
 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic