Я думаю о том, чтобы начать использовать умные указатели в моей работе с qt. Меня смущает, как умные указатели будут работать с сборкой мусора в Qt. Весь Qt опирается на то, что дочерний QObject конструирует с QObject * parent в качестве аргумента ctor и, следовательно, включает сборку мусора.
Например:
QWidget* mWidget = new QWidget(this);//Here we not only
//ensure that mWidget will be deleted
//when its parent is deleted, but also tell qt,
//that mWidget is not a window, but belongs to
//parent's layout
Теперь, если я хочу обернуть mWidget в умный указатель.
typedef QScopedPointer<QWidget> WidgPtr;
WidgPtr mWidget = WidgPtr(new QWidget(this));
Но теперь, когда вызывается родительский dtor, он дважды вызывает указатель mWidget. Во-первых, из-за сборки мусора, во-вторых, когда вызывается умный указатель dtor.
Конечно, мы можем создать mWidget без родителя, а затем изменить некоторые флаги, чтобы отключить поведение окна или вызвать setParent () (но затем mWidget снова будет удален дважды). Но для меня слишком много сделать такую сложную инициализацию, чтобы иметь возможность использовать умные указатели вместо сырых указателей.
Или может я что-то пропустил?
Благодарю.
QScopedPointer
а также QSharedPointer
не знают, живет или умирает их целевой объект, поэтому, если вы будете хранить умный указатель где-либо еще, кроме переменных-членов, тогда да, в вашем случае деструктор может быть вызван дважды. Вот почему такие умные указатели плохо подходят для QObjects
(но они все еще могут быть полезны, когда у вашего объекта нет родителя).
Если вам нужно сохранить осторожный указатель на QObject
использовать QPointer
: он станет нулевым, как только объект будет уничтожен, так что вы можете delete
это в любой момент, не опасаясь причинить какой-либо хаос. Но помни это QPointer
НЕ уничтожит указанный объект в деструкторе. В большинстве случаев вы должны строить иерархии QObjects
и просто позвольте системе владения очистить память.
Других решений пока нет …