QObject中的d_ptr是这样定义的
QScopedPointer<QObjectData> d_ptr;
其中QScopedPointer定义如下:
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
typedef T *QScopedPointer:: *RestrictedBool;
public:
explicit inline QScopedPointer(T *p = 0) : d(p)
{
}
inline ~QScopedPointer()
{
T *oldD = this->d;
Cleanup::cleanup(oldD);
}
inline T &operator*() const
{
Q_ASSERT(d);
return *d;
}
inline T *operator->() const
{
Q_ASSERT(d);
return d;
}
inline bool operator!() const
{
return !d;
}
#if defined(Q_QDOC)
inline operator bool() const
{
return isNull() ? 0 : &QScopedPointer::d;
}
#else
inline operator RestrictedBool() const
{
return isNull() ? 0 : &QScopedPointer::d;
}
#endif
inline T *data() const
{
return d;
}
inline bool isNull() const
{
return !d;
}
inline void reset(T *other = 0)
{
if (d == other)
return;
T *oldD = d;
d = other;
Cleanup::cleanup(oldD);
}
inline T *take()
{
T *oldD = d;
d = 0;
return oldD;
}
inline void swap(QScopedPointer<T, Cleanup> &other)
{
qSwap(d, other.d);
}
typedef T *pointer;
protected:
T *d;
private:
Q_DISABLE_COPY(QScopedPointer)
};
QObjectData定义如下:
class Q_CORE_EXPORT QObjectData {
public:
virtual ~QObjectData() = 0;
QObject *q_ptr;
QObject *parent;
QObjectList children;
uint isWidget : 1;
uint blockSig : 1;
uint wasDeleted : 1;
uint isDeletingChildren : 1;
uint sendChildEvents : 1;
uint receiveChildEvents : 1;
uint isWindow : 1; //for QWindow
uint unused : 25;
int postedEvents;
QDynamicMetaObjectData *metaObject;
QMetaObject *dynamicMetaObject() const;
};
QScopedPointer是一个模版类,传入QObjectData参数,在QObject的类定义中,有这么一句话:
inline QObject *parent() const { return d_ptr->parent; }
d_ptr是QScopedPointer对象,如何有parent成员呢?
d_ptr并不是一个指针,只是一个变量而已,并不能写->,一开始没有发现这个问题,那为什么可以写成->呢,如果开始考虑这个问题,那就已经接近答案了,QScopedPointer重载了->操作符,返回了d指针,而d指针就是QObjectData类型的,所以可以写成d_ptr->parent,这里展开就是这样的形式d_ptr->()->parent,最后一次还是要调用内置的->操作符。这就是箭头操作符的重载。