web-dev-qa-db-fra.com

Quelle est la différence entre les classes QPointer, QSharedPointer et QWeakPointer dans Qt?

J'ai lu des documentations Qt sur les classes QPointer, QSharedPointer et QWeakPointer. Ça dit:

  1. QPointer est une classe de modèle qui fournit des pointeurs protégés vers des objets Qt et se comporte comme un pointeur C++ normal, sauf qu'elle est automatiquement définie sur 0 lorsque l'objet référencé est détruit et qu'aucun "pointeur suspendu" n'est produit.

  2. La classe QSharedPointer contient une référence forte à un pointeur partagé.

  3. La classe QWeakPointer contient une référence faible à un pointeur partagé.

Ma question est "Quelle est la différence entre ces cours?". c'est-à-dire quelle est la différence entre un pointeur vers un objet et une référence à un pointeur? Sont-ils tous des pointeurs vers des objets avec des mécanismes et des comportements différents?

26
Nejat

QPointer:
QPointer ne peut pointer que vers QObject instances. Il sera automatiquement défini sur nullptr si l'objet pointé est détruit. C'est un pointeur faible spécialisé pour QObject.

Considérez ce fragment:

QObject *obj = new QObject;
QPointer<QObject> pObj(obj);
delete obj;
Q_ASSERT(pObj.isNull()); // pObj will be nullptr now

QSharedPointer
Un pointeur compté par référence. L'objet réel ne sera supprimé que lorsque tous les pointeurs partagés seront détruits. Équivalent à 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

Notez que tant qu'il y a un pointeur partagé, l'objet n'est pas supprimé!

QWeakPointer:
Peut contenir une référence faible à un pointeur partagé. Il n'empêchera pas l'objet d'être détruit et est simplement réinitialisé. Équivalent à std::weak_ptr, Où lock est équivalent à 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());

Cela peut être utilisé si vous avez besoin d'accéder à un objet contrôlé par un autre module.

Pour utiliser un pointeur faible, vous devez le convertir en QSharedPointer. Vous ne devez jamais baser une décision sur la validité du pointeur faible . Vous pouvez uniquement utiliser data() ou isNull() pour déterminer que le pointeur est nul.

En règle générale, pour utiliser un pointeur faible, vous devez le convertir en pointeur partagé car une telle opération garantit que l'objet survivra aussi longtemps que vous l'utiliserez. Cela équivaut à "verrouiller" l'objet pour l'accès et est la seule façon correcte d'utiliser l'objet pointé par un pointeur faible.

59
king_nak