栈对象和堆对象的传递,QT信号与槽

connect(&communication_thread,&QThread::started,communication,&Communication::RunFunction);

在 Qt 中, connnect里的4个参数都是传的地址,信号和槽函数都是成员变量,属于栈对象

&communication_thread 使用取地址符 & 是因为 communication_thread 是一个 栈对象(stack-allocated object),而非通过 new 创建的堆对象。以下是详细解释:


1. 为什么这里用 &

(1) communication_thread 的存储位置
  • 栈对象
    在代码中,communication_thread 是直接声明的成员变量(如 QThread communication_thread;),属于 栈对象(或类成员对象)。它的生命周期由作用域或父对象管理,无需手动 delete
  • 取地址
    因为 moveToThread() 需要传入一个 QThread*(指针),而 communication_thread 是对象本身,所以需要用 & 取其地址:
    communication->moveToThread(&communication_thread); // 传递 QThread*
    
(2) 对比 new 创建的线程对象

如果 communication_thread 是通过 new 创建的堆对象,则应直接传递指针:

QThread* communication_thread = new QThread(this); // 堆对象
communication->moveToThread(communication_thread); // 无需 &,已是指针

2. 关键区别:栈对象 vs 堆对象

特性栈对象(QThread thread;堆对象(QThread* thread = new QThread;
内存管理自动销毁(作用域结束或父对象析构时)需手动 delete 或设置父对象自动删除
指针传递需用 & 取地址(如 &thread直接传递指针(如 thread
典型场景生命周期与类/函数一致时使用需动态控制生命周期时使用

3. 为什么此处选择栈对象?

  • 生命周期绑定
    通常线程对象 (QThread) 会作为成员变量存在,其生命周期与所属类(如 MainWindow)一致,无需手动管理。
  • 安全性
    栈对象在父对象析构时自动销毁,避免内存泄漏。

4. 注意事项

  1. 线程对象销毁顺序
    确保线程对象 (communication_thread) 的析构发生在所有依赖它的对象(如 communication)之后,否则可能引发崩溃。

    • 如果 communication_thread 是成员变量,通常会在类的析构函数中停止线程:
      ~MainWindow() {
          communication_thread.quit();
          communication_thread.wait();
      }
      
  2. 跨线程信号槽
    如果 communication 对象通过 moveToThread 移入线程,其槽函数将在新线程执行,需确保线程安全(如避免直接操作 UI)。


5. 完整示例

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow() {
        communication = new Communication(); // 堆对象
        communication->moveToThread(&communication_thread); // 栈对象取地址
        connect(&communication_thread, &QThread::started, communication, &Communication::run);
        communication_thread.start();
    }

    ~MainWindow() {
        communication_thread.quit();
        communication_thread.wait();
        delete communication; // 需手动删除堆对象
    }

private:
    QThread communication_thread; // 栈对象
    Communication* communication; // 堆对象
};

总结

  • &communication_thread
    因为 communication_thread 是栈对象,需用 & 取地址以传递指针给 moveToThread
  • 何时用 &
    当对象是栈对象或成员对象时,取地址传递指针;堆对象直接传递指针本身。
  • 生命周期管理
    确保线程和依赖对象的销毁顺序正确,避免悬空指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值