qt 垃圾收集和智能指针

Ale*_*der 5 c++ qt smart-pointers

我想开始在我的 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         
Run Code Online (Sandbox Code Playgroud)

现在,如果我想将 mWidget 包装到智能指针中。

 typedef QScopedPointer<QWidget> WidgPtr;
 WidgPtr mWidget = WidgPtr(new QWidget(this));
Run Code Online (Sandbox Code Playgroud)

但是现在当父的 dtor 被调用时,它会在 mWidget 的指针上调用 delete 两次。首先是由于垃圾收集,其次是调用智能指针 dtor 时。

当然,我们可以在没有父级的情况下构造 mWidget,然后更改一些标志以关闭窗口行为或调用 setParent()(但是再次 mWidget 将被删除两次)。但是对我来说,为了能够使用智能指针而不是原始指针而进行如此复杂的初始化太过分了。或者也许我错过了什么?谢谢。

Sep*_*ram 5

QScopedPointer并且QSharedPointer不知道它们的目标对象是生还是死,因此如果您将智能指针保留在成员变量之外的任何其他位置,那么是的,在您的情况下,析构函数可能会被调用两次。这就是为什么这些类型的智能指针不适合QObjects(但是当您的对象没有父对象时它们仍然有用)。

如果您需要保留指向 的受保护指针QObject,请使用QPointer: 一旦对象被销毁,它将变为 null,因此您可以随时使用delete它而不必担心造成任何混乱。但请记住,QPointer这不会破坏析构函数中引用的对象。在大多数情况下,您应该构建 的层次结构QObjects并让所有权系统清理内存。

  • 在 Qt4 中,比 QPointer 更喜欢 QWeakPointer,以获得更好的性能(阅读两者的文档)。在即将到来的 Qt5 中,我似乎记得 QPointer 又好了,但不要相信我的话...... (2认同)