Общий указатель волшебным образом не знает, когда вы удаляете объект, на который он указывает. Будет ошибкой вручную удалять объект, время жизни которого управляется общим указателем. Поскольку окно самоудаляется при закрытии, теперь вы получаете оборванные общие указатели.
Следовательно, вы не можете использовать QSharedPointer
с виджетом Qt::WA_DeleteOnClose
.
Что вам нужно, так это указатель, который отслеживает, существует ли еще виджет. Такой указатель QPointer
, он делает именно то, что вам нужно. Этот указатель предназначен для сброса себя на ноль, когда QObject
уничтожается.
Обратите внимание, что QPointer
— это слабый указатель, он не удалит окно, когда оно выйдет за пределы области видимости.
Если вам нужен указатель-владелец, который позволяет удалить базовый QObject
, есть способ сделать это:
template <typename T> class ScopedQObjectPointer {
Q_DISABLE_COPY(ScopedQObjectPointer)
QPointer<T> m_ptr;
inline void check() const {
Q_ASSERT(m_ptr && (m_ptr->thread() == 0
|| m_ptr->thread() == QThread::currentThread()));
}
public:
explicit ScopedQObjectPointer(T* obj = 0) : m_ptr(obj) {}
ScopedQObjectPointer(ScopedQObjectPointer &&other) : m_ptr(other.take()) {}
~ScopedQObjectPointer() { check(); delete m_ptr; }
operator T*() const { check(); return m_ptr; }
T & operator*() const { check(); return *m_ptr; }
T * operator->() const { check(); return m_ptr; }
T * data() const { check(); return m_ptr; }
T * take() { check(); T * p = m_ptr; m_ptr.clear(); return p; }
void reset(T * other) { check(); delete m_ptr; m_ptr = other; }
operator bool() const { check(); return m_ptr; }
};
Поскольку мы разрешаем удаление объекта с помощью других средств, кроме указателя, обращение к объекту из нескольких потоков является ошибкой. Если объект должен быть удален в другом потоке, возникает состояние гонки между проверкой нуля и использованием разыменованного объекта. Таким образом, QPointer
или ScopedObjectPointer
можно использовать только из потока объекта. Это прямо утверждается. Q_ASSERT
становится недоступным в релизных сборках и не влияет на производительность.
person
Kuba hasn't forgotten Monica
schedule
14.08.2014