QObject的d_ptr成员——箭头符号的重载

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,最后一次还是要调用内置的->操作符。这就是箭头操作符的重载。

你可能感兴趣的:(C++-运算符重载)