3

主.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();
}

我的对象.cpp:

#include "myobject.h"

MyObject::MyObject(QObject *parent) :
    QObject(parent)
{
}

void MyObject::doWork()
{
    qDebug() << "Hi";
    QThread::currentThread()->quit();
    return;
}

我的对象.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,存在内存泄漏,但我该如何解决呢?我想我必须返回事件循环然后调用退出?但问题是我无权访问事件循环。

4

2 回答 2

1

没有内存泄漏。如果您坚持它的对象模型对象树和所有权, Qt 确实会正确清理。我也喜欢遵循文档中的示例

这是您引用的示例,并在deleteLater().

主文件

#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)

希望有帮助。

于 2013-04-20T00:53:42.547 回答
0

我是链接上的海报。实际上默认连接没有内存泄漏。通过子类化 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 

并且对象cObject被泄露。

线程何时有效退出是未记录的。所以我不能争论这种行为是否总是一样的。一种可能性是让线程启动器负责进行清理工作。例如:

 void cleanup(){
  cThread->exit();
  cThread->wait();
  delete cThread;
  delete cObject;
 }

总结一下,您不必使用此代码修复任何内容。

于 2013-04-25T10:14:07.090 回答