Make it possible to use QPointer<const T>

This is possible with QWeakPointer, so allow it for migrating
code too.

In the process, replace the QPointerBase with a member variable for
simplicity. The functionality of the QPointerBase is replaced
by a TypeSelector template.

Change-Id: I3b4c77bdeda2b863cc33e84a3da8a25bae928c8c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Stephen Kelly 2013-02-10 10:57:43 +01:00 committed by The Qt Project
parent 60cde0bd14
commit cc7239da8d
4 changed files with 33 additions and 35 deletions

3
dist/changes-5.1.0 vendored
View File

@ -64,6 +64,9 @@ QtCore
inside the pattern string, as well as the numerical index of each
named capturing group.
- QPointer
* It is now possible to create a QPointer with a const templated type.
-
QtGui

View File

@ -50,56 +50,44 @@ QT_BEGIN_NAMESPACE
class QVariant;
class QPointerBase
{
QWeakPointer<QObject> wp;
protected:
inline QPointerBase() : wp() { }
inline QPointerBase(QObject *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine! (even though public)
inline ~QPointerBase() { }
inline QObject* data() const
{ return wp.data(); }
inline void assign(QObject *p)
{ wp.assign(p); }
inline bool isNull() const
{ return wp.isNull(); }
inline void clear()
{ wp.clear(); }
};
template <class T>
class QPointer : private QPointerBase
class QPointer
{
template<typename U>
struct TypeSelector
{
typedef QObject Type;
};
template<typename U>
struct TypeSelector<const U>
{
typedef const QObject Type;
};
typedef typename TypeSelector<T>::Type QObjectType;
QWeakPointer<QObjectType> wp;
public:
inline QPointer() { }
inline QPointer(T *p) : QPointerBase(p) { }
inline QPointer(T *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine!
inline ~QPointer() { }
inline QPointer<T> &operator=(T* p)
{ QPointerBase::assign(p); return *this; }
{ wp.assign(static_cast<QObjectType*>(p)); return *this; }
inline T* data() const
{ return static_cast<T*>(QPointerBase::data()); }
{ return static_cast<T*>( wp.data()); }
inline T* operator->() const
{ return data(); }
inline T& operator*() const
{ return *data(); }
inline operator T*() const
{ return data(); }
#ifdef Q_QDOC
inline bool isNull() const;
inline void clear();
#else
using QPointerBase::isNull;
using QPointerBase::clear;
#endif
inline bool isNull() const
{ return wp.isNull(); }
inline void clear()
{ wp.clear(); }
};
template <class T> Q_DECLARE_TYPEINFO_BODY(QPointer<T>, Q_MOVABLE_TYPE);

View File

@ -639,7 +639,7 @@ private:
public:
#else
template <class X> friend class QSharedPointer;
friend class QPointerBase;
template <class X> friend class QPointer;
#endif
template <class X>

View File

@ -65,6 +65,7 @@ private slots:
void threadSafety();
void qvariantCast();
void constPointer();
};
void tst_QPointer::constructors()
@ -384,6 +385,12 @@ void tst_QPointer::qvariantCast()
// QPointer<int> sop = qPointerFromVariant<int>(v);
}
void tst_QPointer::constPointer()
{
// Compile-time test that QPointer<const T> works.
QPointer<const QFile> fp = new QFile;
delete fp.data();
}
QTEST_MAIN(tst_QPointer)