Я прочитал из документации Qt о QPointer
, QSharedPointer
а также QWeakPointer
классы. Это говорит:
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()
определить, что указатель является нулевым.
Как правило, чтобы использовать слабый указатель, вы должны преобразовать его в общий указатель, поскольку такая операция гарантирует, что объект будет существовать до тех пор, пока вы его используете. Это эквивалентно «блокированию» объекта для доступа и является единственным правильным способом использования объекта, на который указывает слабый указатель.
Других решений пока нет …