diff options
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 54 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer.h | 8 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 41 |
3 files changed, 103 insertions, 0 deletions
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 58a9a021d0..180f45eb56 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -372,6 +372,43 @@ */ /*! + \class QEnableSharedFromThis + \inmodule QtCore + \brief A base class that allows to obtain a QSharedPointer for an object already managed by a shared pointer + \since 5.4 + + You can inherit this class when you need to create a QSharedPointer + from any instance of a class -- for instance, from within the + object itself. The key point is that the "obvious" technique of + just returning QSharedPointer<T>(this) can not be used, because + this winds up creating multiple distinct QSharedPointer objects + with separate reference counts. For this reason you must never + create more than one QSharedPointer from the same raw pointer. + + QEnableSharedFromThis defines two member functions called + sharedFromThis() that return a QSharedPointer<T> and + QSharedPointer<const T>, depending on constness, to \c this: + + \code + class Y: public QEnableSharedFromThis<Y> + { + public: + QSharedPointer<Y> f() + { + return sharedFromThis(); + } + }; + + int main() + { + QSharedPointer<Y> p(new Y()); + QSharedPointer<Y> y = p->f(); + Q_ASSERT(p == y); // p and q must share ownership + } + \endcode +*/ + +/*! \fn QSharedPointer::QSharedPointer() Creates a QSharedPointer that points to null (0). @@ -924,6 +961,23 @@ */ /*! + \fn QSharedPointer<T> QEnableSharedFromThis::sharedFromThis() + \since 5.4 + + If \c this (that is, the subclass instance invoking this method) is being + managed by a QSharedPointer, returns a shared pointer instance pointing to + \c this; otherwise returns a QSharedPointer holding a null pointer. +*/ + +/*! + \fn QSharedPointer<const T> QEnableSharedFromThis::sharedFromThis() const + \overload + \since 5.4 + + Const overload of sharedFromThis(). +*/ + +/*! \fn bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) \relates QSharedPointer diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index d9de48b7f4..431868ee08 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -131,6 +131,14 @@ public: QSharedPointer<T> lock() const; }; +template <class T> +class QEnableSharedFromThis +{ +public: + QSharedPointer<T> sharedFromThis(); + QSharedPointer<const T> sharedFromThis() const; +}; + template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2); template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2); template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 7dafa4981c..fe79aa1db1 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -91,6 +91,7 @@ template<typename T> inline void qt_sharedpointer_cast_check(T *) { } // template <class T> class QWeakPointer; template <class T> class QSharedPointer; +template <class T> class QEnableSharedFromThis; class QVariant; @@ -479,6 +480,14 @@ private: delete d; } + template <class X> + inline void enableSharedFromThis(const QEnableSharedFromThis<X> *ptr) + { + ptr->initializeFromSharedPointer(*this); + } + + inline void enableSharedFromThis(...) {} + template <typename Deleter> inline void internalConstruct(T *ptr, Deleter deleter) { @@ -499,6 +508,7 @@ private: internalSafetyCheckAdd(d, ptr); #endif d->setQObjectShared(ptr, true); + enableSharedFromThis(ptr); } template <class X> @@ -707,6 +717,37 @@ public: T *value; }; +template <class T> +class QEnableSharedFromThis +{ +protected: +#ifdef Q_COMPILER_DEFAULT_MEMBERS + QEnableSharedFromThis() = default; +#else + Q_DECL_CONSTEXPR QEnableSharedFromThis() {} +#endif + QEnableSharedFromThis(const QEnableSharedFromThis &) {} + QEnableSharedFromThis &operator=(const QEnableSharedFromThis &) { return *this; } + +public: + inline QSharedPointer<T> sharedFromThis() { return QSharedPointer<T>(weakPointer); } + inline QSharedPointer<const T> sharedFromThis() const { return QSharedPointer<const T>(weakPointer); } + +#ifndef Q_NO_TEMPLATE_FRIENDS +private: + template <class X> friend class QSharedPointer; +#else +public: +#endif + template <class X> + inline void initializeFromSharedPointer(const QSharedPointer<X> &ptr) const + { + weakPointer = ptr; + } + + mutable QWeakPointer<T> weakPointer; +}; + // // operator== and operator!= // |