Deprecate the use of QWeakPointer to track QObjects.
The main problem with using QWeakPointer to track QObjects is that it has API to convert to QSharedPointer, which is undefined behavior. There is no need to overload the meaning of QWeakPointer with QObject tracking. QPointer is more suitable and should be used instead. Because QPointer is implemented in terms of QWeakPointer, we need to add some overloads which are not deprecated. Change-Id: If0333e4800c9fd277629cc69185c9ca3e4e7e81d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
77a03ebd8d
commit
ee7fa67eb0
@ -57,7 +57,7 @@ class QPointerBase
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline QPointerBase() : wp() { }
|
inline QPointerBase() : wp() { }
|
||||||
inline QPointerBase(QObject *p) : wp(p) { }
|
inline QPointerBase(QObject *p) : wp(p, true) { }
|
||||||
// compiler-generated copy/move ctor/assignment operators are fine! (even though public)
|
// compiler-generated copy/move ctor/assignment operators are fine! (even though public)
|
||||||
inline ~QPointerBase() { }
|
inline ~QPointerBase() { }
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ protected:
|
|||||||
{ return wp.data(); }
|
{ return wp.data(); }
|
||||||
|
|
||||||
inline void assign(QObject *p)
|
inline void assign(QObject *p)
|
||||||
{ wp = p; }
|
{ wp.assign(p); }
|
||||||
|
|
||||||
inline bool isNull() const
|
inline bool isNull() const
|
||||||
{ return wp.isNull(); }
|
{ return wp.isNull(); }
|
||||||
|
@ -107,9 +107,8 @@
|
|||||||
it makes no use of additional structure or reference counting.
|
it makes no use of additional structure or reference counting.
|
||||||
|
|
||||||
Finally, QPointer holds a pointer to a QObject-derived object, but it
|
Finally, QPointer holds a pointer to a QObject-derived object, but it
|
||||||
does so weakly. QPointer can be replaced by QWeakPointer in almost all
|
does so weakly. QWeakPointer has the same functionality, but its use for
|
||||||
cases, since they have the same functionality. See
|
that function is deprecated.
|
||||||
\l{QWeakPointer#tracking-qobject} for more information.
|
|
||||||
|
|
||||||
\section1 Optional pointer tracking
|
\section1 Optional pointer tracking
|
||||||
|
|
||||||
@ -181,8 +180,7 @@
|
|||||||
(see below for information on custom deleters). The strong reference
|
(see below for information on custom deleters). The strong reference
|
||||||
count can also exceptionally be -1, indicating that there are no
|
count can also exceptionally be -1, indicating that there are no
|
||||||
QSharedPointers attached to an object, which is tracked too. The only
|
QSharedPointers attached to an object, which is tracked too. The only
|
||||||
case where this is possible is that of
|
case where this is possible is that of QWeakPointers tracking a QObject.
|
||||||
\l{QWeakPointer#tracking-qobject}{QWeakPointers tracking a QObject}.
|
|
||||||
|
|
||||||
The weak reference count controls the lifetime of the d-pointer itself.
|
The weak reference count controls the lifetime of the d-pointer itself.
|
||||||
It can be thought of as an internal/intrusive reference count for
|
It can be thought of as an internal/intrusive reference count for
|
||||||
@ -369,8 +367,7 @@
|
|||||||
deleted or not in another context.
|
deleted or not in another context.
|
||||||
|
|
||||||
QWeakPointer objects can only be created by assignment from a
|
QWeakPointer objects can only be created by assignment from a
|
||||||
QSharedPointer. The exception is pointers derived from QObject: in that
|
QSharedPointer.
|
||||||
case, QWeakPointer serves as a replacement to QPointer.
|
|
||||||
|
|
||||||
It's important to note that QWeakPointer provides no automatic casting
|
It's important to note that QWeakPointer provides no automatic casting
|
||||||
operators to prevent mistakes from happening. Even though QWeakPointer
|
operators to prevent mistakes from happening. Even though QWeakPointer
|
||||||
@ -389,45 +386,6 @@
|
|||||||
not get deleted (or if you only need the pointer value) and the cost of
|
not get deleted (or if you only need the pointer value) and the cost of
|
||||||
creating a QSharedPointer using toStrongRef() is too high.
|
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 of classes that derive 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.
|
|
||||||
|
|
||||||
\omit
|
\omit
|
||||||
\secton1 QWeakPointer internals
|
\secton1 QWeakPointer internals
|
||||||
|
|
||||||
@ -764,6 +722,7 @@
|
|||||||
/*!
|
/*!
|
||||||
\fn QWeakPointer::QWeakPointer(const QObject *obj)
|
\fn QWeakPointer::QWeakPointer(const QObject *obj)
|
||||||
\since 4.6
|
\since 4.6
|
||||||
|
\deprecated
|
||||||
|
|
||||||
Creates a QWeakPointer that holds a weak reference directly to the
|
Creates a QWeakPointer that holds a weak reference directly to the
|
||||||
QObject \a obj. This constructor is only available if the template type
|
QObject \a obj. This constructor is only available if the template type
|
||||||
@ -776,18 +735,19 @@
|
|||||||
Note that QWeakPointers created this way on arbitrary QObjects usually
|
Note that QWeakPointers created this way on arbitrary QObjects usually
|
||||||
cannot be promoted to QSharedPointer.
|
cannot be promoted to QSharedPointer.
|
||||||
|
|
||||||
\sa QSharedPointer, QWeakPointer#tracking-qobject
|
\sa QSharedPointer, QPointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QWeakPointer &QWeakPointer::operator=(const QObject *obj)
|
\fn QWeakPointer &QWeakPointer::operator=(const QObject *obj)
|
||||||
\since 4.6
|
\since 4.6
|
||||||
|
\deprecated
|
||||||
|
|
||||||
Makes this QWeakPointer hold a weak reference directly to the QObject
|
Makes this QWeakPointer hold a weak reference directly to the QObject
|
||||||
\a obj. This function is only available if the template type \tt T is
|
\a obj. This function is only available if the template type \tt T is
|
||||||
QObject or derives from it.
|
QObject or derives from it.
|
||||||
|
|
||||||
\sa QWeakPointer#tracking-qobject
|
\sa QPointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -585,13 +585,18 @@ public:
|
|||||||
|
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
// special constructor that is enabled only if X derives from QObject
|
// special constructor that is enabled only if X derives from QObject
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 0)
|
||||||
template <class X>
|
template <class X>
|
||||||
inline QWeakPointer(X *ptr) : d(ptr ? d->getAndRef(ptr) : 0), value(ptr)
|
QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? d->getAndRef(ptr) : 0), value(ptr)
|
||||||
{ }
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 0)
|
||||||
template <class X>
|
template <class X>
|
||||||
inline QWeakPointer &operator=(X *ptr)
|
QT_DEPRECATED inline QWeakPointer &operator=(X *ptr)
|
||||||
{ return *this = QWeakPointer(ptr); }
|
{ return *this = QWeakPointer(ptr); }
|
||||||
|
#endif
|
||||||
|
|
||||||
inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
|
inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
|
||||||
{ if (d) d->weakref.ref(); }
|
{ if (d) d->weakref.ref(); }
|
||||||
@ -664,6 +669,17 @@ private:
|
|||||||
public:
|
public:
|
||||||
#else
|
#else
|
||||||
template <class X> friend class QSharedPointer;
|
template <class X> friend class QSharedPointer;
|
||||||
|
friend class QPointerBase;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class X>
|
||||||
|
inline QWeakPointer &assign(X *ptr)
|
||||||
|
{ return *this = QWeakPointer<X>(ptr, true); }
|
||||||
|
|
||||||
|
#ifndef QT_NO_QOBJECT
|
||||||
|
template <class X>
|
||||||
|
inline QWeakPointer(X *ptr, bool) : d(ptr ? d->getAndRef(ptr) : 0), value(ptr)
|
||||||
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void internalSet(Data *o, T *actual)
|
inline void internalSet(Data *o, T *actual)
|
||||||
|
Loading…
Reference in New Issue
Block a user