1. 程式人生 > >Qt中無處不在的d指標為何方神聖

Qt中無處不在的d指標為何方神聖

在研究QCoreApplication類的程式碼時,無意間弄明白了“d_func()”和“d指標”的來源:

class Q_CORE_EXPORT QCoreApplication
#ifndef QT_NO_QOBJECT
    : public QObject
#endif
{
    ……
    Q_DECLARE_PRIVATE(QCoreApplication)
public:
   ……
    ~QCoreApplication();
   ……
protected:
    QCoreApplication(QCoreApplicationPrivate &p);

#ifdef QT_NO_QOBJECT
    QScopedPointer<QCoreApplicationPrivate> d_ptr;
#endif
};

上面的程式碼中出現了一個紅“Q_DECLARE_PRIVATE”,接下來看看這個巨集的作用。

template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
template <typename Wrapper> static inline typename Wrapper::pointer\
                    qGetPtrHelper(const Wrapper &p) { return p.data(); }
#define Q_DECLARE_PRIVATE(Class) \
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
    friend class Class##Private;

發現這個展開後引入了d_func()這個函式。但是“d指標”和這個巨集又有什麼關係呢?那就要說到另一個巨集“Q_D”看如下的程式碼:

#define Q_D(Class) Class##Private * const d = d_func()
從程式碼中可知,d_func()和d指標是緊密聯絡的。在Qt原始碼中“d_func()函式”和“d指標”的使用無處不在!

在接下的過程中又發現了另一組巨集“Q_DECLARE_PUBLIC、Q_Q”,程式碼如下:

#define Q_DECLARE_PUBLIC(Class)                                    \
	inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
	inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \
	friend class Class;

#define Q_Q(Class) Class * const q = q_func()
這組巨集引入了“q_func()函式”和“q指標”,這兩個在Qt程式碼中遇見較少,留待以後研究。