From a654df7aa466775b0f9a6e4b33319c228f5634b2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 14:56:49 +0200 Subject: Add QWeakPointer::data, which thread-unsafely returns the tracked pointer This function allows one to retrieve the pointer out of a QWeakPointer without promoting it to QSharedPointer first. That means there are no guarantees that the object won't get deleted. Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qsharedpointer.cpp | 76 ++++++++++++++++++++++++++++++++- src/corelib/tools/qsharedpointer_impl.h | 1 + 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 2ca612e..ef4dfac 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -128,7 +128,7 @@ To access the pointer that QWeakPointer is tracking, you must first create a QSharedPointer object and verify if the pointer - is null or not. + is null or not. See QWeakPointer::toStrongRef() for more information. \sa QSharedPointer */ @@ -210,6 +210,8 @@ If \tt T is a derived type of the template parameter of this class, QSharedPointer will perform an automatic cast. Otherwise, you will get a compiler error. + + \sa QWeakPointer::toStrongRef() */ /*! @@ -362,6 +364,8 @@ Returns a weak reference object that shares the pointer referenced by this object. + + \sa QWeakPointer::QWeakPointer(const QSharedPointer &) */ /*! @@ -478,10 +482,78 @@ */ /*! + \fn T *QWeakPointer::data() const + \since 4.6 + + Returns the value of the pointer being tracked by this QWeakPointer, + \b without ensuring that it cannot get deleted. To have that guarantee, + use toStrongRef(), which returns a QSharedPointer object. If this + function can determine that the pointer has already been deleted, it + returns 0. + + It is ok to obtain the value of the pointer and using that value itself, + like for example in debugging statements: + + \code + qDebug("Tracking %p", weakref.data()); + \endcode + + However, dereferencing the pointer is only allowed if you can guarantee + by external means that the pointer does not get deleted. For example, + if you can be certain that no other thread can delete it, nor the + functions that you may call. + + If that is the case, then the following code is valid: + + \code + // this pointer cannot be used in another thread + // so other threads cannot delete it + QWeakPointer weakref = obtainReference(); + + Object *obj = weakref.data(); + if (obj) { + // if the pointer wasn't deleted yet, we know it can't get + // deleted by our own code here nor the functions we call + otherFunction(obj); + } + \endcode + + Use this function with care. + + \sa isNull(), toStrongRef() +*/ + +/*! \fn QSharedPointer QWeakPointer::toStrongRef() const Promotes this weak reference to a strong one and returns a - QSharedPointer object holding that reference. + QSharedPointer object holding that reference. When promoting to + QSharedPointer, this function verifies if the object has been deleted + already or not. If it hasn't, this function increases the reference + count to the shared object, thus ensuring that it will not get + deleted. + + Since this function can fail to obtain a valid strong reference to the + shared object, you should always verify if the conversion succeeded, + by calling QSharedPointer::isNull() on the returned object. + + For example, the following code promotes a QWeakPointer that was held + to a strong reference and, if it succeeded, it prints the value of the + integer that was held: + + \code + QWeakPointer weakref; + + // ... + + QSharedPointer strong = weakref.toStrongRef(); + if (strong) + qDebug() << "The value is:" << *strong; + else + qDebug() << "The value has already been deleted"; + \endcode + + \sa QSharedPointer::QSharedPointer(const QWeakPointer &) */ /*! diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 9fa8df4..e8e3812 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -492,6 +492,7 @@ public: inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; } inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; } inline bool operator !() const { return isNull(); } + inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; } inline QWeakPointer() : d(0), value(0) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } -- cgit v0.12