QPointer
、QSharedPointer
、およびQWeakPointer
クラスに関するQtのドキュメントを読みました。それは言います:
QPointer
は、Qtオブジェクトへの保護されたポインターを提供するテンプレートクラスであり、通常のC++ポインターと同様に動作しますが、参照オブジェクトが破棄され、「ダングリングポインター」が生成されない場合、自動的に0に設定されます。
QSharedPointer
クラスは、共有ポインターへの強い参照を保持します。
QWeakPointer
クラスは、共有ポインターへの弱い参照を保持します。
私の質問は「これらのクラスの違いは何ですか?」です。つまり、オブジェクトへのポインターとポインターへの参照の違いは何ですか?それらはすべて、異なるメカニズムと動作を持つオブジェクトへのポインターですか?
QPointer:QPointer
は、QObject
インスタンスのみを指すことができます。オブジェクトへのポインタが破壊されると、自動的にnullptr
に設定されます。 QObject
に特化した弱いポインターです。
このフラグメントを考えてみましょう:
_QObject *obj = new QObject;
QPointer<QObject> pObj(obj);
delete obj;
Q_ASSERT(pObj.isNull()); // pObj will be nullptr now
_
QSharedPointer
参照カウントされたポインター。実際のオブジェクトは、すべての共有ポインターが破棄されたときにのみ削除されます。 _std::shared_ptr
_と同等。
_int *pI = new int;
QSharedPointer<int> pI1(pI);
QSharedPointer<int> pI2 = pI1;
pI1.clear();
// pI2 is still pointing to pI, so it is not deleted
pI2.clear();
// No shared pointers anymore, pI is deleted
_
共有ポインタがある限り、オブジェクトは削除されないことに注意してください!
QWeakPointer:
共有ポインタへの弱い参照を保持できます。オブジェクトが破壊されるのを防ぐことはなく、単にリセットされます。 _std::weak_ptr
_と同等です。lock
はtoStrongRef
と同等です。
_int *pI = new int;
QSharedPointer<int> pI1(pI);
QWeakPointer<int> pI2 = pI1;
pI1.clear();
// No shared pointers anymore, pI is deleted
//
// To use the shared pointer, we must "lock" it for use:
QSharedPointer<int> pI2_locked = pI2.toStrongRef();
Q_ASSERT(pI2_locked.isNull());
_
これは、別のモジュールによって制御されるオブジェクトへのアクセスが必要な場合に使用できます。
弱いポインターを使用するには、QSharedPointer
に変換する必要があります。弱いポインターが有効であるという判断に基づいて絶対に判断しないでください。 data()
またはisNull()
のみを使用して、ポインターがヌルであることを判別できます。
一般に、弱いポインターを使用するには、共有ポインターに変換する必要があります。そのような操作により、オブジェクトを使用している限りオブジェクトが存続することが保証されるためです。これは、アクセスのためにオブジェクトを「ロック」することと同等であり、弱いポインタが指すオブジェクトを使用する唯一の正しい方法です。