main.cpp:
#include <QCoreApplication>
#include <QtCore>
#include "myobject.h"
QThread* cThread;
MyObject* cObject;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cThread = new QThread();
cObject = new MyObject();
cObject->moveToThread(cThread);
QObject::connect(cThread, SIGNAL(started()),
cObject, SLOT(doWork()));
QObject::connect(cThread, SIGNAL(finished()),
cThread, SLOT(deleteLater()));
QObject::connect(cThread, SIGNAL(finished()),
cObject, SLOT(deleteLater()));
cThread->start();
return a.exec();
}
myobject.cpp:
#include "myobject.h"
MyObject::MyObject(QObject *parent) :
QObject(parent)
{
}
void MyObject::doWork()
{
qDebug() << "Hi";
QThread::currentThread()->quit();
return;
}
myobject.h:
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QtCore>
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0);
signals:
public slots:
void doWork();
};
#endif // MYOBJECT_H
显然,根据:https://stackoverflow.com/a/16062717,内存泄漏,但我该如何修复?我想我必须返回事件循环,然后调用quit?但问题是我无法访问事件循环。
没有内存泄漏。如果你坚持使用它的对象模型、对象树和所有权,Qt确实可以很好地清理。我也喜欢下面的例子。
以下是您引用的示例,并在deleteLater()
上添加了观察结果。
main.cpp
#include <QCoreApplication>
#include <QtCore>
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public slots:
void deleteLater()
{
qDebug() << Q_FUNC_INFO;
QThread::deleteLater();
}
};
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0){}
signals:
public slots:
void deleteLater()
{
qDebug() << Q_FUNC_INFO;
QObject::deleteLater();
}
void doWork()
{
qDebug() << "Hi";
QThread::currentThread()->quit(); // It is supposed to stop here, but it doesn't.
return;
for (int i = 0; i < 1000000; i++) {
qDebug() << i;
}
}
};
QThread* cThread;
MyObject* cObject;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cThread = new MyThread();
cObject = new MyObject();
cObject->moveToThread(cThread);
QObject::connect(cThread, SIGNAL(started()),
cObject, SLOT(doWork()));
QObject::connect(cThread, SIGNAL(finished()),
cThread, SLOT(deleteLater()));
QObject::connect(cThread, SIGNAL(finished()),
cObject, SLOT(deleteLater()));
cThread->start();
return a.exec();
}
输出:
Hi
void __thiscall MyObject::deleteLater(void)
void __thiscall MyThread::deleteLater(void)
希望能有所帮助。
我是链接上的海报。事实上,默认连接没有内存泄漏。通过对deleteLater和像@phyatt这样的析构函数进行子类化,您获得了:
Hi
void MyObject::deleteLater()
virtual MyObject::~MyObject() Being deleted
void MyThread::deleteLater()
virtual MyThread::~MyThread() Being deleted
但如果你在连接中使用Qt::QueueConnection
,你会得到:
Hi
void MyThread::deleteLater()
virtual MyThread::~MyThread() Being deleted
并且对象CCD_ 3被泄漏。
当线程有效地退出时,它是未记录的。因此,我无法争辩这种行为是否永远都是一样的。一种可能性是让线程启动器负责执行清理工作。例如:
void cleanup(){
cThread->exit();
cThread->wait();
delete cThread;
delete cObject;
}
要结束一切,您不必使用此代码修复任何内容。