QSharedPointer和QObject::deleteLater

9

我遇到了这样一种情况:一个由QSharedPointer管理的对象发出信号,表示它已经完成了它的目的,并且准备很快被删除(在发射我的readyForDeletion信号后执行离开函数)。当使用普通指针时,我只需在对象上调用QObject::deleteLater,但是对于由QSharedPointer管理的实例则不可能。我的解决方法如下:

template<typename T>
class QSharedPointerContainer : public QObject
{
   QSharedPointer<T> m_pSharedObj;

public:

   QSharedPointerContainer(QSharedPointer<T> pSharedObj)
      : m_pSharedObj(pSharedObj)
   {} // ==> ctor

}; // ==> QSharedPointerContainer

template<typename T>
void deleteSharedPointerLater(QSharedPointer<T> pSharedObj)
{
   (new QSharedPointerContainer<T>(pSharedObj))->deleteLater();
} // ==> deleteSharedPointerLater

这种方法可以很好地解决问题,但使用这种方法会有很多开销(例如分配一个新的 QObject 等)。有没有更好的解决方案来处理这种情况?


4
所以,您有一个由多个对象共同拥有的对象(它们都声称拥有所有权),但同时它又管理自己的生命周期(通过具有 readyForDeletion 信号)。听起来你有一个非常混乱的所有权情况。与其寻找解决方法,不如先搞清楚谁真正负责这个对象,因此应该由谁删除它。 - Sebastian Redl
我必须同意@Sabastian的观点。当他的评论出现时,我正要发表类似的评论。如果您的对象跟踪何时可以安全删除它,请使用普通指针,并在创建该对象的任何类上处理“readyForDeletion”信号。 - Dave Mateer
感谢您的评论。在我的实际程序中,事情要复杂得多,然而,看一下抽象问题,就会清楚地发现,在这种情况下使用QSharedPointer根本不是一个好主意。 - athre0z
2个回答

22

您可以使用QSharedPointer构造函数Deleter

删除器参数指定此对象的自定义删除器。 当强引用计数降至0时,将调用自定义删除器,而不是operator delete()。例如, 这对于在QObject上调用deleteLater()非常有用:

 QSharedPointer<MyObject> obj =
         QSharedPointer<MyObject>(new MyObject, &QObject::deleteLater);

哦,我怎么会忘记看到这个呢。显然,这是所描述问题的最佳解决方案,但由于它在我的特殊情况下更有意义,我选择坚持使用主问题评论中提供的解决方案。 - athre0z

1

一种替代方案是使用QPointer而不是QSharedPointer,引用文档:

QPointer类是一个模板类,提供了对QObject的保护指针。

保护指针QPointer的行为类似于普通的C++指针T *,但当引用的对象被销毁时,它会自动设置为0(与普通的C++指针不同,在这种情况下它们变成“悬空指针”)。 T必须是QObject的子类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接