5. 回调函数开发

匿名函数

qt中有匿名函数,就是lambda函数参考 跳转

回调函数

回调函数的表现方式有几种:

函数指针

qt 中void*作为回调函数
在Qt中,你可以使用函数指针作为回调函数。这里有一个简单的例子,展示了如何使用void*作为回调函数的参数。

#include <QObject>
#include <QDebug>
 
class MyClass : public QObject {
    Q_OBJECT
public:
    using Callback = void(*)(void*);
 
    MyClass(QObject *parent = nullptr) : QObject(parent) {}
 
    void registerCallback(Callback callback, void* userData) {
        // 保存回调函数和用户数据
        m_callback = callback;
        m_userData = userData;
    }
 
    void triggerCallback() {
        if (m_callback) {
            // 调用回调函数
            m_callback(m_userData);
        }
    }
 
private:
    Callback m_callback = nullptr;
    void* m_userData = nullptr;
};
 
// 回调函数示例
void myCallback(void* userData) {
    qDebug() << "Callback called with user data:" << userData;
}
 
int main() {
    MyClass obj;
 
    // 注册回调函数
    obj.registerCallback(myCallback, (void*)"Hello World");
 
    // 触发回调
    obj.triggerCallback();
 
    return 0;
}

std::function

qt std::function传参
在Qt中,std::function是一种通用的多态函数封装。它可以容纳各种可调用对象,包括函数、lambda表达式、bind表达式等。你可以使用std::function来传递参数给Qt的信号和槽机制。

以下是一个简单的例子,演示如何使用std::function作为Qt的槽函数:

#include <QObject>
#include <functional>
 
class MyClass : public QObject
{
    Q_OBJECT
 
public:
    MyClass(QObject *parent = nullptr) : QObject(parent) {}
 
signals:
    void mySignal(int param);
 
public slots:
    void mySlot(int param);
};
 
void MyClass::mySlot(int param)
{
    // 处理param
}
 
int main()
{
    MyClass obj;
    std::function<void(int)> func = std::bind(&MyClass::mySlot, &obj, std::placeholders::_1);
 
    QObject::connect(&obj, &MyClass::mySignal, &func);
 
    // 当发送mySignal时,会调用mySlot
    emit obj.mySignal(42);
 
    return 0;
}

lambda转函数指针与std::funtion

参考跳转

将 Lambda 表达式转换为函数指针

要将 Lambda 表达式转换为函数指针,有几个重要的注意事项:

  1. Lambda 必须没有捕获(Capture):即捕获列表必须为空 [ ]。只有没有捕获的 lambda 表达式(纯函数)才能转换为函数指针。
  2. 显式指定函数签名:对于转换为函数指针的情况,lambda 表达式的参数和返回类型需要显式指定。
#include <iostream>

// 定义一个不捕获变量的 lambda
auto lambda = [](int a, int b) -> int {
    return a + b;
};

// 将 lambda 转换为函数指针
int (*func_ptr)(int, int) = lambda;

int main() {
    // 使用函数指针调用 lambda 表达式
    std::cout << func_ptr(3, 4) << std::endl;  // 输出 7
    return 0;
}

lambda 表达式转换std::function

如果 lambda 表达式有捕获,只能使用 std::function 来存储它。这是因为带捕获的 lambda 需要存储额外的状态,不能直接转换为普通函数指针。

示例

#include <iostream>
#include <functional>

int main() {
    // 定义一个捕获变量的 lambda
    int factor = 10;
    auto lambda = [factor](int x) -> int {
        return x * factor;
    };

    // 使用 std::function 存储带捕获的 lambda
    std::function<int(int)> func = lambda;

    // 使用调用
    std::cout << func(5) << std::endl;  // 输出 50
    return 0;
}

虽然你不能将带捕获的 lambda 直接转换为普通函数指针,std::function 提供了一个灵活的和类型安全的方式来存储和调用带捕获的 lambda。

通用 lambda 和自动返回类型

在 C++14 和之后的标准中,引入了一些新特性,如通用 lambda 和自动返回类型,这使得 lambda 表达式的使用变得更加广泛和灵活。

#include <iostream>
#include <functional>

int main() {
    // 定义一个通用 lambda,可以接受任何类型的参数
    auto generic_lambda = [](auto x, auto y) {
        return x + y;
    };

    // 使用 std::function 存储通用 lambda
    std::function<int(int, int)> func = generic_lambda;

    // 使用调用
    std::cout << func(3, 4) << std::endl;  // 输出 7

    // 直接使用 lambda
    std::cout << generic_lambda(1.5, 2.7) << std::endl;  // 输出 4.2

    return 0;
}



总结

需要捕获就要使用std::function
其他情况可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱搞事的程小猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值