QT中的資料指標

2021-04-25 11:10:23 字數 1699 閱讀 8914

在此中以qglwidget為例作為乙個說明:

在原始碼標頭檔案中看到該類的宣告部分,第二行就是

declare_private(qglwidget)

這是乙個巨集的定義,展開以後是這個樣子的:

#define q_declare_private(class) /

inline class##private* d_func() /

inline const class##private* d_func() const /

friend class class##private;

也就是說定義了乙個內聯函式去得到乙個私有資料成員的指標,大家在這裡會得到將d_ptr強制轉換而來的乙個指標。指標的型別為qglwidgetprivate(這裡的##是將前後連線起來的,編譯器所完成的工作,我這裡是以qglwidget為例的,所以是qglwidgetprivate資料),我在看這裡的時候有個疑問是這個資料指標存在於**,什麼時候被分配了記憶體空間的。

下面是我的解釋:

我們在呼叫qglwidget的建構函式時,會先呼叫基類即qwidget的建構函式,我們其實是這樣呼叫的:

qglwidget::qglwidget(qwidget *parent, const qglwidget* sharewidget, qt::windowflags f)

: qwidget(*(new qglwidgetprivate), parent, f | qt::mswindowsowndc)

qwidget::qwidget(qwidgetprivate &dd, qwidget* parent, qt::windowflags f)

: qobject(dd, 0), qpaintdevice()

依此類推,我們有理由相信,這個資料指標最終指向的是qobject中所定義的乙個指標d_ptr。另外,我們還可以看到,這些最後帶有private的類也是有繼承關係的,這就解釋了,在各個類中d_ptr

是如何呈現自身的特性的。

另外還有一點就是qglwidgetprivate中的資料又是在何時被初始化的呢,是在乙個init函式中被初始化的,其呼叫如下顯示:

qglwidget::qglwidget(qwidget *parent, const qglwidget* sharewidget, qt::windowflags f)

: qwidget(*(new qglwidgetprivate), parent, f | qt::mswindowsowndc)

還有兩點需要注意的是,兩個巨集:

#define q_declare_public(class)                                    /

inline class* q_func() /

inline const class* q_func() const /

friend class class;

這個巨集被用於資料類中呼叫去得到其所對應的實體類(例如:qglwidgetprivate對應於qglwidget)

#define q_declare_private(class) /

inline class##private* d_func() /

inline const class##private* d_func() const /

friend class class##private;

這個巨集剛好與之前的巨集相反,用於實體類用於得對應的資料類成員。

資料隱藏之Qt中d指標詳解

最近看到 有用到了qt中的q d指標,就去學習了下,發現真的很好用,因此寫一篇文章總結下。class cstudent 如果我們這個類屬於乙個動態庫,那麼向外部提供乙個dll時,就會暴露我類的資料結構,使用者便會知道,原來姓名是string型別,年齡是int型別等等,這是我不想看到的,也不符合我把其...

智慧型指標類模板(中) Qt中的智慧型指標

qt中的智慧型指標 qpointer 當其指向的物件被銷毀時,它會被自動置空 析構時不會自動銷毀所指向的物件 qsharedpointer 引用計數型智慧型指標 可以被自由的拷貝和賦值 當引用計數為0時才刪除指向的物件 include include using namespace std clas...

智慧型指標類模板(中) Qt中的智慧型指標

qt中的智慧型指標 qpointer 當其指向的物件被銷毀時,它會被自動置空 析構時不會自動銷毀所指向的物件 qsharedpointer 引用計數型智慧型指標 可以被自由的拷貝和賦值 當引用計數為0時才刪除指向的物件 include include using namespace std clas...