正确实现 QThread 的方法(附示例)

这篇技术博客探讨了在 Qt 框架中正确实现 QThread 类的方法。传统 Qt 文档建议继承 QThread 类并重写其 run 方法,这虽然在某些情况下可行,但并不是推荐的最佳实践。以下内容将探讨这种方法的利弊,并提供一个更好的实现 QThread 的示例。

原始示例:继承 QThread 并重写 run 方法

在 Qt 4.7 的 QThread 文档中,推荐下面的实现方式:

cpp 复制代码
class MyThread : public QThread
{
public:
    void run();
};

void MyThread::run()
{
    QTcpSocket socket;
    // 连接 QTcpSocket 的信号到一些有意义的槽
    ...
    socket.connectToHost(hostName, portNumber);
    exec();
}

在这种方法中,我们通过重写 run 方法来启动新的线程,并在该线程中运行事件循环。然而,这种方式存在一些问题,尤其是当在多线程中操作对象时,可能会引发线程安全问题。

推荐方法:使用 QObject 及其信号槽机制

一种更推荐的方法是将实际的工作放在 QObject 的子类中,并使用 QThread 来运行该对象。这种方法更符合面向对象编程的原则,并且更安全。以下是一个完整的示例:

工作器类 (Worker)

cpp 复制代码
class Worker : public QObject
{
    Q_OBJECT
public slots:
    void doWork(const QString &parameter) {
        // 执行具体的工作
        // ...
        emit resultReady(result);
    }

signals:
    void resultReady(const QString &result);
};

在这个示例中,我们定义了一个 Worker 类,它继承自 QObject 并包含一个用于执行工作的槽和一个用于发送结果的信号。

控制器类 (Controller)

cpp 复制代码
class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    Controller() {
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);

        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);

        workerThread.start();
    }

    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }

public slots:
    void handleResults(const QString &result) {
        // 处理工作结果
    }

signals:
    void operate(const QString &parameter);
};

Controller 类中,我们创建了一个 Worker 实例并将其移到新线程中,并通过信号和槽机制连接各个事件和处理函数。这种方法避免了直接继承 QThread,使得代码更清晰易懂,同时也更加安全和稳定。

结论

尽管继承 QThread 并重写其 run 方法是 Qt 文档中介绍的一种实现线程的方式,但为了更好的线程管理和代码维护,更推荐使用上面介绍的使用 QObject 和信号槽机制的方法。这不仅符合面向对象编程的原则,还能避免潜在的线程安全问题,提升代码的稳定性和可读性。

相关推荐
十五年专注C++开发2 分钟前
CMake进阶:模块模式示例FindOpenCL.cmake详解
开发语言·c++·cmake·跨平台编译
Yupureki41 分钟前
《算法竞赛从入门到国奖》算法基础:入门篇-离散化
c语言·数据结构·c++·算法·visual studio
散峰而望43 分钟前
OJ 题目的做题模式和相关报错情况
java·c语言·数据结构·c++·vscode·算法·visual studio code
疋瓞1 小时前
C/C++查缺补漏《5》_智能指针、C和C++中的数组、指针、函数对比、C和C++中内存分配概览
java·c语言·c++
闻林禹1 小时前
c++并发编程
开发语言·c++
CTO Plus技术服务中1 小时前
一栈式、系统性的C、C++、Go、网络安全、Linux运维开发笔记和面试笔记
c++·web安全·golang
zc.ovo1 小时前
线段树优化建图
数据结构·c++·算法·图论
WaWaJie_Ngen1 小时前
C++实现一笔画游戏
c++·算法·游戏·游戏程序·课程设计
小尧嵌入式1 小时前
【Linux开发一】类间相互使用|继承类和构造写法|虚函数实现多态|五子棋游戏|整数相除混合小数|括号使用|最长问题
开发语言·c++·算法·游戏
你的冰西瓜1 小时前
C++中的map容器详解
开发语言·c++·stl