qt-lambda信号槽机制

想要调查,lambda信号槽在用完后会不会自己回收

写入成员变量

private:  
    std::function<void()> lambdaSlot;  

初始化

lambdaSlot = []() {
        qDebug() << "Lambda slot executed";
        // 可访问类成员(如this指针)
    };

cpp代码展示

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    qDebug() << "Lambda slot executed1";
    std::function<void()> lambdaSlot1;
    lambdaSlot1 = []() {
            qDebug() << "Lambda slot executed 临时";
            // 可访问类成员(如this指针)
        };
    lambdaSlot2 = []() {
        qDebug() << "Lambda slot executed";
        // 可访问类成员(如this指针)
    };
    lambdaSlot = &lambdaSlot1;
    qDebug() << lambdaSlot;


    connect(ui->pushButton_2,&QPushButton::clicked,lambdaSlot1);
}


MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    (*lambdaSlot)();
//    lambdaSlot2();
}

lambda信号槽是独立的,即使使用std::function<void()> lambdaSlot1;生成对象在转为槽函数,也是不行的,因为,在传入的过程中生成了另一个对象
证明过程
请添加图片描述

现象,pushButton_2点击有效,pushButton点击直接死机
在这里插入图片描述

那么,QT C++lambda槽函数的生命周期,是否与信号发送对象绑定?

Qt C++ 中,lambda 槽函数的生命周期 不直接信号发送对象 绑定,而是取决于 lambda 本身的捕获方式接收对象(receiver)的生命周期

Lambda 槽函数的生命周期规则

(1) 无捕获的 Lambda(无状态)

connect(sender, &Sender::signal, []() { 
    qDebug() << "No capture"; 
});
  • 生命周期:独立于任何对象,类似于普通函数。
  • 风险:如果 sender 被销毁,连接会自动断开(Qt 默认行为),但 lambda 本身仍然有效(如果被其他地方引用)。

(2) 有捕获的 Lambda(有状态)

int value = 42;
connect(sender, &Sender::signal, [value]() { 
    qDebug() << "Captured value:" << value; 
});
  • 生命周期
    • 如果 receiver(接收对象)是 this(当前对象)
      • Lambda 会被存储在 receiver 的内部数据结构中(如 QObjectPrivate)。
      • receiver 被销毁时,Qt 会自动断开所有相关连接,避免悬空引用。
    • 如果 receiver 是另一个对象
      • Lambda 的生命周期取决于该 receiver 对象的生命周期。
      • 如果 receiver 先被销毁,而 sender 仍然存在,可能会导致未定义行为(除非手动管理连接)。

(3) 使用 QPointershared_ptr 管理生命周期

如果 lambda 捕获了指针或引用,建议使用智能指针或 QPointer 防止悬空引用:

QPointer<QObject> safeObj = someObj;
connect(sender, &Sender::signal, [safeObj]() {
    if (safeObj) {
        qDebug() << "Object still exists";
    }
});

信号发送对象(sender)的影响

  • 默认情况下,Qt 的信号槽连接是 AutoConnection(自动选择 DirectConnectionQueuedConnection)。
  • 如果 sender 被销毁
    • 所有由 sender 发出的连接都会被自动断开(Qt 内部管理)。
    • 但 lambda 本身可能仍然存在(如果被其他对象持有)。

关键结论

场景生命周期管理风险
无捕获 Lambda独立于任何对象无悬空风险
有捕获 Lambda + receiverthisreceiverthis) 管理receiver 销毁时自动断开
有捕获 Lambda + 外部 receiverreceiver 管理如果 receiver 先销毁,可能导致悬空
捕获原始指针/引用需手动管理(如 QPointer悬空引用风险

结论

  • Lambda 槽函数的生命周期 主要取决于 捕获的变量receiver 对象,而不是 信号发送对象
  • Qt 默认会管理 senderreceiver 之间的连接,但 有捕获的 lambda 仍需手动管理悬空引用
  • 最佳方式:尽量使用 this 作为 receiver,或使用智能指针确保安全。

总结

所以,使用lambda槽函数,一定要确保是一次性的,不会循环创建的,否则,不保证是否会有内存泄漏!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世转神风-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值