【问题标题】:qt garbage collection and smart pointersqt 垃圾收集和智能指针
【发布时间】:2012-10-03 23:57:04
【问题描述】:

我正在考虑在我的 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又会被删除两次)。但对我来说,做如此复杂的初始化只是为了能够使用智能指针而不是原始指针,这太过分了。 或者我想念什么? 谢谢。

【问题讨论】:

  • 如果QObject 子销毁机制有效,为什么需要智能指针?
  • 因为智能指针提供了一些超越垃圾收集的优势。例如,如果在删除父小部件之前引发异常,它们可以防止内存泄漏。再举一个例子,它们可以防止指针对象等的意外复制。
  • 对象所有权是 NOT 垃圾回收。 Qt 甚至 C++ 中都没有 GC。

标签: c++ qt smart-pointers


【解决方案1】:

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

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

【讨论】:

  • 在 Qt4 中,更喜欢 QWeakPointer 而不是 QPointer,以获得更好的性能(请阅读两者的文档)。在即将到来的 Qt5 中,我似乎记得 QPointer 再次很好,但不要相信我的话......
  • @hyde,谢谢你的评论,我不知道 :) 显然,这是真的:QWeakPointer 兼作QPointer 的替代品。我想知道他们为什么要保留QPointer
猜你喜欢
  • 1970-01-01
  • 2011-09-05
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 2012-03-21
相关资源
最近更新 更多