В чем разница между классами QPointer, QSharedPointer и QWeakPointer в Qt?

Я прочитал из документации Qt о QPointer, QSharedPointer а также QWeakPointer классы. Это говорит:

  1. QPointer это шаблонный класс, который предоставляет защищенные указатели на объекты Qt и ведет себя как обычный указатель C ++, за исключением того, что он автоматически устанавливается равным 0, когда ссылочный объект уничтожается и не создаются «висячие указатели».

  2. QSharedPointer Класс содержит строгую ссылку на общий указатель.

  3. QWeakPointer класс содержит слабую ссылку на общий указатель.

Мои вопросы: «В чем разница между этими классами?». т.е. в чем разница между указателем на объект и ссылкой на указатель? Все ли они указатели на объекты с различными механизмами и поведением?

25

Решение

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() определить, что указатель является нулевым.

Как правило, чтобы использовать слабый указатель, вы должны преобразовать его в общий указатель, поскольку такая операция гарантирует, что объект будет существовать до тех пор, пока вы его используете. Это эквивалентно «блокированию» объекта для доступа и является единственным правильным способом использования объекта, на который указывает слабый указатель.

56

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]