diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-08-12 14:13:24 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-08-12 14:13:24 (GMT) |
commit | c792951aba5fd897610e199c457846d0b6b0690d (patch) | |
tree | 8843e93273ce11c9e3afc8574bf5d7e6063ebc74 /src/corelib/tools | |
parent | a6905066d18c29c55944653678e85698c9babc6e (diff) | |
parent | fe5d0c32887b17a76c259bea951beaaaad675968 (diff) | |
download | Qt-c792951aba5fd897610e199c457846d0b6b0690d.zip Qt-c792951aba5fd897610e199c457846d0b6b0690d.tar.gz Qt-c792951aba5fd897610e199c457846d0b6b0690d.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt into qtscript-jsc-backend
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 111 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer.h | 3 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 21 |
3 files changed, 121 insertions, 14 deletions
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 644ccc3..e3e1db6 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -98,15 +98,14 @@ access made to the data being guarded: if it's a non-const access, it creates a copy atomically for the operation to complete. - QExplicitlySharedDataPointer behaves like QSharedDataPointer, - except that it only detaches if - QExplicitlySharedDataPointer::detach() is explicitly called. + QExplicitlySharedDataPointer is a variant of QSharedDataPointer, except + that it only detaches if QExplicitlySharedDataPointer::detach() is + explicitly called (hence the name). - Finally, QPointer holds a pointer to a QObject-derived object, but - it does so weakly. QPointer is similar, in that behaviour, to - QWeakPointer: it does not allow you to prevent the object from - being destroyed. All you can do is query whether it has been - destroyed or not. + Finally, QPointer holds a pointer to a QObject-derived object, but it + does so weakly. QPointer can be replaced by QWeakPointer in almost all + cases, since they have the same functionality. See + \l{QWeakPointer#tracking-qobject} for more information. \sa QSharedDataPointer, QWeakPointer */ @@ -123,12 +122,65 @@ directly, but it can be used to verify if the pointer has been deleted or not in another context. - QWeakPointer objects can only be created by assignment - from a QSharedPointer. - - To access the pointer that QWeakPointer is tracking, you - must first create a QSharedPointer object and verify if the pointer - is null or not. See QWeakPointer::toStrongRef() for more information. + QWeakPointer objects can only be created by assignment from a + QSharedPointer. The exception is pointers derived from QObject: in that + case, QWeakPointer serves as a replacement to QPointer. + + It's important to note that QWeakPointer provides no automatic casting + operators to prevent mistakes from happening. Even though QWeakPointer + tracks a pointer, it should not be considered a pointer itself, since it + doesn't guarantee that the pointed object remains valid. + + Therefore, to access the pointer that QWeakPointer is tracking, you must + first promote it to QSharedPointer and verify if the resulting object is + null or not. QSharedPointer guarantees that the object isn't deleted, so + if you obtain a non-null object, you may use the pointer. See + QWeakPointer::toStrongRef() for more an example. + + QWeakPointer also provides the QWeakPointer::data() method that returns + the tracked pointer without ensuring that it remains valid. This function + is provided if you can guarantee by external means that the object will + not get deleted (or if you only need the pointer value) and the cost of + creating a QSharedPointer using toStrongRef() is too high. + + That function can also be used to obtain the tracked pointer for + QWeakPointers that cannot be promoted to QSharedPointer, such as those + created directly from a QObject pointer (not via QSharedPointer). + + \section1 Tracking QObject + + QWeakPointer can be used to track deletion classes derives from QObject, + even if they are not managed by QSharedPointer. When used in that role, + QWeakPointer replaces the older QPointer in all use-cases. QWeakPointer + is also more efficient than QPointer, so it should be preferred in all + new code. + + To do that, QWeakPointer provides a special constructor that is only + available if the template parameter \tt T is either QObject or a class + deriving from it. Trying to use that constructor if \tt T does not derive + from QObject will result in compilation errors. + + To obtain the QObject being tracked by QWeakPointer, you must use the + QWeakPointer::data() function, but only if you can guarantee that the + object cannot get deleted by another context. It should be noted that + QPointer had the same constraint, so use of QWeakPointer forces you to + consider whether the pointer is still valid. + + QObject-derived classes can only be deleted in the thread they have + affinity to (which is the thread they were created in or moved to, using + QObject::moveToThread()). In special, QWidget-derived classes cannot be + created in non-GUI threads nor moved there. Therefore, guaranteeing that + the tracked QObject has affinity to the current thread is enough to also + guarantee that it won't be deleted asynchronously. + + Note that QWeakPointer's size and data layout do not match QPointer, so + it cannot replace that class in a binary-compatible manner. + + Care must also be taken with QWeakPointers created directly from QObject + pointers when dealing with code that was compiled with Qt versions prior + to 4.6. Those versions may not track the reference counters correctly, so + QWeakPointers created from QObject should never be passed to code that + hasn't been recompiled. \sa QSharedPointer */ @@ -412,6 +464,35 @@ */ /*! + \fn QWeakPointer::QWeakPointer(const QObject *obj) + \since 4.6 + + Creates a QWeakPointer that holds a weak reference directly to the + QObject \a obj. This constructor is only available if the template type + \tt T is QObject or derives from it (otherwise a compilation error will + result). + + You can use this constructor with any QObject, even if they were not + created with \l QSharedPointer. + + Note that QWeakPointers created this way on arbitrary QObjects usually + cannot be promoted to QSharedPointer. + + \sa QSharedPointer, QWeakPointer#tracking-qobject +*/ + +/*! + \fn QWeakPointer &QWeakPointer::operator=(const QObject *obj) + \since 4.6 + + Makes this QWeakPointer hold a weak reference to directly to the QObject + \a obj. This function is only available if the template type \tt T is + QObject or derives from it. + + \sa QWeakPointer#tracking-qobject +*/ + +/*! \fn QWeakPointer &QWeakPointer::operator=(const QWeakPointer<T> &other) Makes this object share \a other's pointer. The current pointer @@ -896,6 +977,8 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge { Q_ASSERT(obj); QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj)); + Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted"); + ExternalRefCountData *that = d->sharedRefcount; if (that) { that->weakref.ref(); diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index e0fe3b1..332883a 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -115,6 +115,9 @@ public: QWeakPointer<T> operator=(const QWeakPointer<T> &other); QWeakPointer<T> operator=(const QSharedPointer<T> &other); + QWeakPointer(const QObject *other); + QWeakPointer<T> operator=(const QObject *other); + T *data() const; void clear(); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 7b3239b..ba479f9 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -121,6 +121,13 @@ namespace QtSharedPointer { typedef T *Basic:: *RestrictedBool; public: typedef T Type; + typedef T element_type; + typedef T value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef ptrdiff_t difference_type; inline T *data() const { return value; } inline bool isNull() const { return !data(); } @@ -490,6 +497,14 @@ class QWeakPointer typedef QtSharedPointer::ExternalRefCountData Data; public: + typedef T element_type; + typedef T value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef ptrdiff_t difference_type; + 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(); } @@ -634,6 +649,12 @@ bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) return ptr2 != ptr1; } +template <class T, class X> +Q_INLINE_TEMPLATE typename T::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1.data() - ptr2.data(); +} + template <class T> Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const { |