如果堆分配的对象被销毁并重新分配指针,Qt 的信号和插槽系统会工作吗?

Posted

技术标签:

【中文标题】如果堆分配的对象被销毁并重新分配指针,Qt 的信号和插槽系统会工作吗?【英文标题】:Will Qt's Signal and Slots system work if a heap-allocated object gets destroyed and the pointer reassigned? 【发布时间】:2016-05-29 19:13:30 【问题描述】:

我有这样的信号和插槽连接:

QGraphicsScene* scene = new QGraphicsScene;
//...
connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), scene, SLOT(doSomething(int)));
//...
delete scene;
scene = new QGraphicsScene;
//...

sceneQGraphicsScene*。有一次我想删除场景并用另一个QGraphicsScene 替换它。因此scene 指向的位置会发生变化。

信号是否仍然有效并被重新路由到新场景?

【问题讨论】:

注意:你应该在动态分配的QObject上使用deleteLater()而不是deleteQGraphicsScene继承自QObject 【参考方案1】:

QObject 的破坏会导致其所有信号和插槽自动断开。

【讨论】:

【参考方案2】:

信号和槽涉及类的实例。每当您将信号连接到插槽时,都会涉及到 QObject 派生类的两个实例(connect 需要两个指向 QObject 的指针才能工作)。

如果您正在处理场景的新实例,则必须将您的插槽连接到这个新实例。这同样适用于新场景的插槽,它必须绑定到...好吧,无论您的软件是否有意义。

【讨论】:

【参考方案3】:

信号是否仍然有效并被重新路由到新场景?

不,它们不会,因为您重新创建场景这一事实只与您相关。从 Qt 的角度来看,您正在创建一个全新的、不相关的对象。 “旧”场景和“新”场景之间没有任何形式的联系——除了你的想法。

但您不需要新场景。您可以清除现有的:

#include "MyWidget_ui.h"

class MyWidget : public QWidget  // Not QMainWindow unless you need it
  Ui::MyWidget ui; // You hold the ui by value.
  QGraphicsScene m_scene;
public:
  MyWidget(QWidget * parent = 0) :
    QWidget(parent)
  
    ui.setupUi(this);
    connect(ui.comboBox, &QComboBox::currentIndexChanged,
            &m_scene, &QGraphicsScene::doSomething);
  
  void test() 
    m_scene.clear();
    // scene is ready to use
  
;

【讨论】:

以上是关于如果堆分配的对象被销毁并重新分配指针,Qt 的信号和插槽系统会工作吗?的主要内容,如果未能解决你的问题,请参考以下文章

动态内存和智能指针

java对象创建的过程

JVM对象内存分配流程

有关C++指针与安全阐述

动态内存——动态内存与智能指针

空悬指针和野指针(Dangling pointer and wild pointer)