diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-08-05 09:26:34 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-08-05 13:16:28 (GMT) |
commit | d1150c5bbf6be125d496ce71570140ea28836ba5 (patch) | |
tree | 2f79bfe2d555d68468cb3d9e56be06f716e6bcbc /src/corelib/tools | |
parent | 520cfa6b6cf4b53a02cc08f01323da036d5b9bea (diff) | |
download | Qt-d1150c5bbf6be125d496ce71570140ea28836ba5.zip Qt-d1150c5bbf6be125d496ce71570140ea28836ba5.tar.gz Qt-d1150c5bbf6be125d496ce71570140ea28836ba5.tar.bz2 |
Restore symmetry between QSharedPointer and QWeakPointer on QObjects.
With the previous commit, you could create a QWeakPointer from any
QObject-derived object. It's possible because QObject now has a
pointer to the QWeakPointer's d-pointer.
However, if you did:
QSharedPointer<QObject> obj(new QObject);
QWeakPointer<QObject> weak1(obj);
QWeakPointer<QObject> weak2(obj.data());
Then weak1 would shared d-pointers with QSharedPointer, but weak2
wouldn't. Also, weak1.toStrongRef() would work, but
weak2.toStrongRef() wouldn't.
This change makes QObject know where the d-pointer created by
QSharedPointer is, so weak2 would get the same d-pointer.
As a nice side-effect, you can check if a given QObject is shared by
trying to promote its QWeakPointer to QSharedPointer.
Reviewed-by: Bradley T. Hughes
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 23 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 3 |
2 files changed, 26 insertions, 0 deletions
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index e2c5e95..10f35c7 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -867,6 +867,29 @@ #if !defined(QT_NO_QOBJECT) #include "../kernel/qobject_p.h" +/*! + \internal + This function is called for a just-created QObject \a obj, to enable + the use of QSharedPointer and QWeakPointer. + + When QSharedPointer is active in a QObject, the object must not be deleted + directly: the lifetime is managed by the QSharedPointer object. In that case, + the deleteLater() and parent-child relationship in QObject only decrease + the strong reference count, instead of deleting the object. +*/ +void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *obj, bool) +{ + Q_ASSERT(obj); + QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj)); + + if (d->sharedRefcount) + qFatal("QSharedPointer: pointer %p already has reference counting", obj); + d->sharedRefcount = this; + + // QObject decreases the refcount too, so increase it up + weakref.ref(); +} + QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj) { Q_ASSERT(obj); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 421db34..8a34362 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -165,7 +165,9 @@ namespace QtSharedPointer { #ifndef QT_NO_QOBJECT Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *); + Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable); #endif + inline void setQObjectShared(...) { } }; // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit) @@ -328,6 +330,7 @@ namespace QtSharedPointer { inline void internalFinishConstruction(T *ptr) { Basic<T>::internalConstruct(ptr); + if (ptr) d->setQObjectShared(ptr, true); #ifdef QT_SHAREDPOINTER_TRACK_POINTERS if (ptr) internalSafetyCheckAdd2(d, ptr); #endif |