SmartPointerList

Ingo Klöcker kloecker at kde.org
Tue Jan 12 23:07:01 GMT 2010


On Tuesday 12 January 2010, Thiago Macieira wrote:
> Em Segunda-feira 11. Janeiro 2010, às 22.52.07, Ingo Klöcker escreveu:
> > On Monday 11 January 2010, Thiago Macieira wrote:
> > > Em Segunda-feira 11 Janeiro 2010, às 10:41:47, Mark Kretschmann
> >
> > escreveu:
> > > > Hey all,
> > > >
> > > > I just wanted to point you to a class that we wrote for Amarok,
> > > > and that we find very useful in many situations, so I was
> > > > wondering if there is any interest in getting it into KDElibs.
> > > >
> > > > What it does is quite simple:
> > > >
> > > > Gives you a QList for pointers (to QObjects), and if an object
> > > > in it is destroyed, its pointer gets removed from this list
> > > > automatically. We found that this can prevent a great deal of
> > > > issues with dangling pointers stored in lists (often a design
> > > > mistake, but it can happen). You be the judge if you find this
> > > > class useful or not.
> > > >
> > > > You can find it here:
> > > >
> > > > http://gitorious.org/amarok/amarok/blobs/master/src/SmartPointe
> > > >rLis
> > > >
> > > >t.h
> > > >
> > > > http://gitorious.org/amarok/amarok/blobs/master/src/SmartPointe
> > > >rLis
> > > >
> > > >t.cpp
> > >
> > > I think this was proposed before.
> > >
> > > But isn't it the same as QList<QWeakPointer<T> > ?
> >
> > From the description I'd have said that it's more like QList<
> > QPointer< T > >, but then I saw that QWeakPointer<T> is a wild mix
> > of QPointer<T> and boost::weak_ptr<T>. *sigh*
> >
> > <quote>
> > QWeakPointer::QWeakPointer ( const QObject * obj )
> > [...]
> > You can use this constructor with any QObject, even if they were
> > not created with QSharedPointer.
> > Note that QWeakPointers created this way on arbitrary QObjects
> > usually cannot be promoted to QSharedPointer.
> > </quote>
> >
> > Why did you have to ruin the beauty of a simple weak-pointer class
> > by adding functionality that's already provided by another class in
> > Qt? Why didn't you follow rule number one ("Be minimal") of
> > http://doc.trolltech.com/qq/qq13-apis.html?
>
> http://labs.trolltech.com/blogs/2009/08/25/count-with-me-how-many-sma
>rt- pointer-classes-does-qt-have/
>
> Because QPointer is madly slow. Don't write new code that uses it.
> Creating, changing or deleting a QPointer requires a function call, a
> global mutex lock and search through a hash -- and the way it's
> built, it actually is just an unsorted list. And when the QObject is
> being deleted, it again locks that mutex and walks over the list of
> QPointers (so it's O(n), but n is 99.9% of the cases 0, and the rest
> of the 0.1% it's 1 and 2).
>
> When I investigated what kind of object would be necessary to replace
> QPointer with something faster, I came to the conclusion I needed a
> refcounted atomic boolean. The boolean would indicate when the object
> had been deleted and the refcounting would allow ~QObject to destroy
> itself at O(1).
>
> Since Qt provides no QAtomicBool, I used QAtomicInt. I only need two
> states in that int, but I had a ref-counted ref-counter, actually.
>
> So, not only was this new class doing exactly the same as
> QWeakPointer ("tell me if this pointer has been deleted"), it also
> had the same internal structure.
>
> There was no need to create a new smart pointer class that did
> exactly the same as QWeakPointer. It only needed the adjustment to be
> able to create from a QObject and the data() function.
>
> Also, keep in mind that no previous QWeakPointer behaviour was
> broken. And even if you use the new way of creating from QObject, if
> the QObject was first placed into a QSharedPointer, the proper
> refcounting is used and you can promote the QWeakPointer to
> QSharedPointer. The way I see it, I was minimal: I did what was
> necessary by reusing existing classes.
>
> We did the same with QScopedPointer: there was an auxiliary class for
> scoped pointers that had refcounts. It was called something crazy
> like QScopedSharedPointer or QScopedRefCountedPointer. Then we
> realised it did the exact same thing as QExplicitlySharedDataPointer,
> so we removed it in favour of the existing one.
>
> PS: The strong pointer semantics for QObject didn't come in 4.6. I
> had the code, but I ran into some issues with deleting in the middle
> of a QWidget hierarchy, so I removed it. I need to do some more
> research before I add it back. Basically, I want QObject itself to
> participate in the refcounting.

Thanks a lot for the explanation, Thiago! It's very much appreciated. I 
guess tomorrow I'll write a bug to replace all QPointers by 
QWeakPointers once we depend on Qt 4.6. (No, I'm not talking about 
KDE. :-) )


Regards,
Ingo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20100113/10d62fc8/attachment.sig>


More information about the kde-core-devel mailing list