Qt

Q_DポインターとQ_Qポインターの詳細な解釈



Deep Interpretation Q_d Pointer



1つ目はQ_Dポインターです。最初にテストケースを貼り付けます。

class TEST class TESTPrivate { public: TESTPrivate(TEST *parent):q_ptr(parent),a(666) {cout << 'TESTPrivate' << endl} ~TESTPrivate() {cout << '~TESTPrivate' int main(int /*argc*/, char */*argv*/[]) { TEST t cout << t.getValue() << endl }

ここで定義されているマクロを見てください。

#define Q_DECLARE_PRIVATE(Class) inline Class##Private* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)) } inline const Class##Private* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)) } friend class Class##Private #define Q_DECLARE_PUBLIC(Class) inline Class* q_func() { return static_cast(q_ptr) } inline const Class* q_func() const { return static_cast(q_ptr) } friend class Class

ここで、手動でマクロ展開を実行します。

// Q_DECLARE_PUBLIC(TEST) inline TEST* q_func() { return static_cast(q_ptr) } inline const TEST* q_func() const { return static_cast(q_ptr) } friend class TEST // Q_DECLARE_PRIVATE(TEST) inline TESTPrivate* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)) } inline const TESTPrivate* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)) } friend class TESTPrivate

これからわか​​るように、実際には、マクロは互いに友達を宣言し、d_ptrポインターを返します。

次のQ_Dマクロを見てみましょう。ここでdポインタとqポインタが定義されていることがわかります。

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

マクロ展開では、いわゆるdポインターは、クラスQ_DECLARE_PRIVATE(TEST)の関数の戻り値を取得するためだけのものであることがわかります。

// Q_D(TEST) TESTPrivate * const d = d_func()

Q_DECLARE_PRIVATE(TEST)で、qGetPtrHelperのマクロを確認します。

template static inline T *qGetPtrHelper(T *ptr) { return ptr }

dポインターの場合、d_func()を呼び出さずにd_ptrから直接コピーを取得し、冗長なfunc関数を削除できます。最終結果は次のとおりです。

class TEST class TESTPrivate { public: TESTPrivate(TEST *parent):q_ptr(parent),a(666) {cout << 'TESTPrivate' << endl} ~TESTPrivate() {cout << '~TESTPrivate'
Q_QポインターはQ_Dポインターに似ており、原則として同じです。別の概念でのみ使用されます。 Q_Dポインターは通常、「Private」クラスのデータにアクセスするために使用され、Q_Qポインターは、Privateクラスを介して「Public」クラスにアクセスするために使用されます。privateクラスはお金を保持するためのウォレットであり、publicクラスはポケットです。 Qtでのこのようなカプセル化により、OOへのダメージを最小限に抑えることができます。結局のところ、友人自体がOOのような原則に違反しています。