SmartPointerList

Thiago Macieira thiago at kde.org
Tue Jan 12 00:22:57 GMT 2010


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/SmartPointerLis
> > >
> > >t.h
> > >
> > > http://gitorious.org/amarok/amarok/blobs/master/src/SmartPointerLis
> > >
> > >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-smart-
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.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Senior Product Manager - Nokia, Qt Development Frameworks
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20100112/29aa67b7/attachment.sig>


More information about the kde-core-devel mailing list