Q_DECLARE_PRIVATE與Q_DECLARE_PUBLIC

Q_DECLARE_PRIVATE與Q_DECLARE_PUBLIC

這兩個宏在Qt的源碼中隨處可見,重要性不言而喻。在 部落格的 Inside Qt Series 系列文章中,他用了3篇文章來講這個問題。

因爲 QObject 本身比較複雜,這兩個宏和一個複雜的東西攪和到一塊,還真是不好理解。不過幸好,這個兩個宏和QObject 沒有必然的聯繫。故接下來,忘記 QObject,看一個普通的C++的類

例子

類 QtServiceController 定義:

class QtServiceController 
{
   Q_DECLARE_PRIVATE(QtServiceController) 
 public:
 QtServiceController(const QString &name);
 //省略其他 
private:
 QtServiceControllerPrivate *d_ptr; 
};

宏定義

宏定義在 QtGlobal(即qglobal.h)頭文件中:

#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;  

#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;

這兩個宏在這看起來真蠻繞的,因爲這個例子太簡單了,兩個宏的威力發揮不出來。反正核心就是:

  • 在 QtServiceController 中通過 d_func() 可以獲得 QtServiceControllerPrivate 的指針 d_ptr

  • 在 QtServiceControllerPrivate 中通過 q_func() 可以獲得 QtServiceController 的指針 q_ptr

Q_D 與 Q_Q

這是另兩個Qt源碼中隨處可見的宏,那麼它們有什麼用呢?

#define Q_D(Class) Class##Private * const d = d_func() 
#define Q_Q(Class) Class * const q = q_func() 

兩個宏展開後分別是對 d_func 和 q_func 兩個函數的調用,返回值分別賦值給 d 和 q 兩個指針變量。

於是:

  • 在 QtServiceController 中的成員函數中,我們只需要添加 Q_D(QtServiceController) 宏,在該函數內就可以直接用 d 來指代 d_ptr

  • 在 QtServiceControllerPrivate 中的成員函數中,我們只需要添加 Q_Q(QtServiceController)宏,在該函數內就可以直接用 q 來指代 q_ptr

d_ptr與q_ptr

繞這麼大圈,爲什麼不直接用 d_ptr 與 q_ptr 呢。在,在我們的例子中,確實可以直接用,而且會更直接更簡單。官方這麼用了,或許是爲了和其他類保持一致吧。

但在其他情況下,這麼做顯然是有意義的,因爲 d_ptr 與 d,q_ptr 與 q 的類型並不一致(比如QObject系列)。這也是爲何宏展開後有cast的原因























發佈了1 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章