垃圾收集和智能指针

时间:2012-10-13 08:35:10

标签: 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         

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

 typedef QScopedPointer<QWidget> WidgPtr;
 WidgPtr mWidget = WidgPtr(new QWidget(this));

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

当然我们可以在没有父节点的情况下构造mWidget,然后更改一些标志来关闭窗口行为或调用setParent()(但是再次mWidget将被删除两次)。但对我来说,做这么复杂的初始化只是为了能够使用智能指针而不是原始指针。 或许我想念一些东西? 感谢。

1 个答案:

答案 0 :(得分:4)

QScopedPointerQSharedPointer不知道他们的目标对象是存在还是死亡,所以如果你将智能指针保留在成员变量之外的其他地方,那么是的,在你的情况下,可能会调用析构函数两次。这就是为什么这些智能指针非常适合QObjects(但是当你的对象没有父对象时它们仍然有用)。

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