C++ Qt对象已删除,但信号未断开

C++ Qt对象已删除,但信号未断开,c++,qt,C++,Qt,在这种情况下,它告诉当qobject被删除时,它的活动连接将被删除。我的情况如下: Work* work = new Work();//->Work derived from QObject Worker* worker = new Worker(work);//->Worker derived from QThread and has the ownership of work connect(work, SIGNAL(percentageComplete(int)), pr

在这种情况下,它告诉当qobject被删除时,它的活动连接将被删除。我的情况如下:

Work* work = new Work();//->Work derived from QObject 
Worker* worker  = new Worker(work);//->Worker derived from QThread and has the ownership of work

connect(work, SIGNAL(percentageComplete(int)), progressDialog, SLOT(setValue(int)));
connect(worker, SIGNAL(finished()),  worker, SLOT(deleteLater()));

progressDialog->show();
worker->start();
在工人的析构函数中,我有:

Worker::~Worker(void){
    if(work != nullptr){
        work->deleteLater();
    }
}
我百分之百确定工作已被删除。我可以通过断点看到它。我甚至可以看到QoObject的Destructor调用


但一些如何删除的工作对象仍接收到信号“完成百分比”。而且因为它被删除了,导致了一个粉碎

我想问,为什么即使删除了对象,信号也没有断开


Worker的析构函数
work->deleteLater()中的第二个问题
删除工作是否正确

我的猜测是,工作对象被移动到工作线程,并且发出的信号将在事件循环中结束,可以稍后传递。此时您可能已终止progressDialog。

我的猜测是,工作对象已移动到工作线程,并且发出的信号将在事件循环中结束,该循环可以稍后传递。此时您可能已关闭progressDialog。

为什么不使用此选项断开所有连接的插槽/信号? 可以在析构函数中调用此函数。您有类似主题的解决方案

为什么不使用断开所有连接的插槽/信号?
可以在析构函数中调用此函数。您有类似主题的解决方案,除非您有一些自定义代码,否则直接使用
QThread

Work* work = new Work(); // no parent
QThread* thread = new QThread();

work->moveToThread(worker);

connect(thread, SIGNAL(started()), work, SLOT(doSomeWork())); // add this function doSomething() in Work class which on completion should emit finished() signal
connect(work, SIGNAL(finished()), thread, SLOT(quit())); // quit the thread
connect(work, SIGNAL(finished()), work, SLOT(deleteLater())); // delete work after job done
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); // delete thread

// if you are using c++11, do this to see Work and Thread deletion
connect(work, &Work::destroyed, [](){ qDebug() << "Work object deleted"; });
connect(thread, &QThread::destroyed, [](){ qDebug() << "Thread deleted"; });

// start the thread now
thread->start();
Work*Work=new Work();//没有父母
QThread*thread=新的QThread();
工作->移动到线程(工作线程);
连接(线程、信号(已启动())、工作、插槽(doSomeWork());//在工作类中添加此函数doSomething(),该函数在完成时应发出finished()信号
连接(工作、信号(完成())、线程、插槽(退出());//退出线程
连接(工作,信号(已完成()),工作,插槽(删除稍后());//工作完成后删除工作
连接(线程、信号(finished())、线程、插槽(deleteLater());//删除线程
//如果您使用的是c++11,请执行此操作以查看工作和线程删除

连接(work,&work::destromined,[](){qDebug(),除非您有一些自定义代码,否则直接使用
QThread

Work* work = new Work(); // no parent
QThread* thread = new QThread();

work->moveToThread(worker);

connect(thread, SIGNAL(started()), work, SLOT(doSomeWork())); // add this function doSomething() in Work class which on completion should emit finished() signal
connect(work, SIGNAL(finished()), thread, SLOT(quit())); // quit the thread
connect(work, SIGNAL(finished()), work, SLOT(deleteLater())); // delete work after job done
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); // delete thread

// if you are using c++11, do this to see Work and Thread deletion
connect(work, &Work::destroyed, [](){ qDebug() << "Work object deleted"; });
connect(thread, &QThread::destroyed, [](){ qDebug() << "Thread deleted"; });

// start the thread now
thread->start();
Work*Work=new Work();//没有父项
QThread*thread=新的QThread();
工作->移动到线程(工作线程);
connect(线程、信号(started())、work、插槽(doSomeWork());//在工作类中添加此函数doSomething(),该函数在完成时应发出finished()信号
连接(工作、信号(完成())、线程、插槽(退出());//退出线程
连接(工作,信号(finished()),工作,插槽(deleteLater());//工作完成后删除工作
连接(线程,信号(finished()),线程,插槽(deleteLater());//删除线程
//如果您使用的是c++11,请执行此操作以查看工作和线程删除

connect(work,&work::destromed,[](){qDebug()发生这种情况是因为有两个线程试图同时使用
work
,没有明显的同步,结果不好

您必须在主线程和工作线程之间封送
工作
的所有权和访问权,以便两个线程不能以不安全的方式同时访问它

Worker
的析构函数未在
Worker
线程中执行!此外,我没有看到任何代码阻止该析构函数在
Worker
线程仍处于活动状态时运行。请注意
QThread
不是线程,而是线程句柄。这是一个欺骗性的名称


遗憾的是,如果没有看到重现问题的完整的示例,就无法回答您的问题。

发生这种情况的原因是,有两个线程试图同时使用
工作
,没有明显的同步,结果不好

您必须在主线程和工作线程之间封送
工作
的所有权和访问权,以便两个线程不能以不安全的方式同时访问它

Worker
的析构函数未在
Worker
线程中执行!此外,我没有看到任何代码阻止该析构函数在
Worker
线程仍处于活动状态时运行。请注意
QThread
不是线程,而是线程句柄。这是一个欺骗性的名称


遗憾的是,如果没有看到重现问题的完整的示例,就无法回答您的问题。

您应该提供一个最小的工作示例。
deleteLater()
应该用于延迟删除对象,因为它可能仍然需要-例如,当您想要删除自己插槽中的对象时。但某些已删除的工作对象仍接收信号“完成百分比”-请澄清您到底看到了什么,在崩溃的地方添加代码,并可能添加回溯。在您的代码中,工作对象正在发射percentageComplete,而不是接收它。如果发送方或接收方被破坏,信号/插槽连接将被破坏,因此我看不到您删除的工作线程如何发出信号。在您的情况下,删除应d是正确的。请重新阅读您自己的问题,它似乎没有意义。为什么
工作
接收
它自己的
完成百分比`信号?此外,我怀疑您在线程方面做得有点错误。如果您在线程中使用
QObject
实例,那么很可能您不应该重写
QThread
.你们都是对的,阅读我自己的问题真的很有帮助。问题完全不同,与lamdba相关。我们不会自动断开连接。现在我该如何处理我的问题?我应该如何编辑它以使其有用或至少不会混淆。你们应该提供一个最简单的工作示例。
deleteLater()
应用于延迟删除对象,因为它可能仍然需要-例如,当您想删除自己插槽中的对象时。”但是