删除信号发送的对象,信号中对象的所有权,Qt

met*_*dos 17 c++ qt signals-slots qt-signals

在这里,我的信号声明:

signals:
    void mySignal(MyClass *);
Run Code Online (Sandbox Code Playgroud)

以及我如何使用它:

MyClass *myObject=new myClass();
emit mySignal(myObject);
Run Code Online (Sandbox Code Playgroud)

这是我的问题:谁负责删除myObject:

  1. 发件人代码,如果在使用myObject之前删除了什么?悬挂指针

  2. 插槽连接到信号,如果没有插槽或连接到信号的多个插槽怎么办?内存泄漏或悬空指针

Qt如何在其内置信号中管理这种情况?它是否使用内部引用计数?

你最好的做法是什么?

And*_*ndo 10

您可以根据需要连接多个插槽的信号,因此您应该确保这些插槽中没有一个能够执行您不希望它们对您的对象执行的操作:

  • 如果您决定将指针作为参数传递,那么您将运行您描述的问题,内存管理 - 这里没有人可以为您工作,因为您必须建立处理分配/删除的策略.有关如何解决此问题的一些想法,请参阅COM世界中的内存管理规则.
  • 如果您决定将参数作为参考传递,那么您不必担心内存管理,而只需要担心以意外方式修改对象的插槽.除非必须,否则ideea不会传递指针 - 如果可以,请使用引用.
  • 如果你决定要传递一个const参考然后根据您的连接类型,QT将通过对象的值给你(看到对一些细节)
  • 避免任何问题,并通过价值:)

有关在信号中传递指针的一些想法,请参阅此问题.


lia*_*iaK 5

对于您的第一个问题,请使用QPointer

对于你的第二个问题,

如果我清楚地理解,即使你正在发送myObject,你仍然可以 myObject在你发出信号的班级中找到参考.那怎么会是内存泄漏还是悬空指针?您仍然可以访问myObject从发射类,是不是?

希望很清楚..

编辑:

根据您的评论,我相信您正在发布/删除插槽中的对象.现在我假设你的问题是,如果(内存释放)插槽被调用一次,两次或根本没有被调用.

您可以使用QPointer.从Qt文档中,

QPointer当您需要存储指向QObject其他人拥有的指针时,有保护的指针()非常有用,因此在您仍然持有对它的引用时可能会被销毁.您可以安全地测试指针的有效性.

Qt文档本身的一个例子,

     QPointer<QLabel> label = new QLabel;
     label->setText("&Status:");
     ...
     if (label)
         label->show();
Run Code Online (Sandbox Code Playgroud)

解释继续这样..

如果在此期间删除QLabel,则label变量将保持0而不是无效地址,并且永远不会执行最后一行.在这里QLabel将是您的MyClass标签是您的myObject.在使用它之前检查Nullity.