我正在考虑在我的qt工作中开始使用智能指针。让我困惑的是,Qt垃圾收集的智能指针将如何。整个Qt都基于子QObject构造的习语,QObject*父作为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
:一旦对象被破坏,它就会变为 null,因此您可以随时delete
它,而不必担心造成任何混乱。但请记住,QPointer
不会销毁析构函数中的引用对象。在大多数情况下,您应该构建QObjects
层次结构,并让所有权系统清理内存。