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. 注意事项
-
线程对象销毁顺序:
确保线程对象 (communication_thread) 的析构发生在所有依赖它的对象(如communication)之后,否则可能引发崩溃。- 如果
communication_thread是成员变量,通常会在类的析构函数中停止线程:~MainWindow() { communication_thread.quit(); communication_thread.wait(); }
- 如果
-
跨线程信号槽:
如果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。- 何时用
&:
当对象是栈对象或成员对象时,取地址传递指针;堆对象直接传递指针本身。 - 生命周期管理:
确保线程和依赖对象的销毁顺序正确,避免悬空指针。
2683

被折叠的 条评论
为什么被折叠?



