C++自学篇 回调函数

前言:
笔者以前只学过C语言,没有学过C++,在新项目中用到C++做开发,因此需要快速学习C++。
注:
1.编译环境:g++.exe (x86_64-posix-seh-rev3, Built by MinGW-W64 project) 11.2.0
2.本篇使用的BaseClass代表基类,使用的DerivedClass代表衍生类。

无类的C语言风格回调函数使用

#include <iostream>
#include <string>

typedef void (*CallbackFunc)(std::string, unsigned int);

typedef struct {
    unsigned int id;
    CallbackFunc callbackFunc;
} CallbackIdInfomation_t;

void run_1(std::string name, unsigned int id)
{
    printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}

void run_2(std::string name, unsigned int id)
{
    printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
}

void run(std::string name, unsigned int id)
{
    const CallbackIdInfomation_t callbackIdInfolist[] = {
        {1, run_1},
        {2, run_2},
        {3, nullptr},
    };
    const int callbackIdInfolistSize = sizeof(callbackIdInfolist) / sizeof(callbackIdInfolist[0]);

    for (int index = 0; index < callbackIdInfolistSize; index++) {
        if (callbackIdInfolist[index].id == id) {
            if (callbackIdInfolist[index].callbackFunc != nullptr) {
                callbackIdInfolist[index].callbackFunc(name, id);
            } else {
                printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
            }
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    run("argv_1", 1);
    run("argv_2", 2);
    run("argv_3", 3);
    run("argv_4", 4);

    return 0;
}

总结:
没有使用类的情况下,使用C语言风格的回调函数可以正常编译/运行。

有类的C语言风格回调函数使用

#include <iostream>
#include <string>

typedef void (*CallbackFunc)(std::string, unsigned int);

typedef struct {
    unsigned int id;
    CallbackFunc callbackFunc;
} CallbackIdInfomation_t;

class BaseClass {
public:
    virtual void run(std::string name, unsigned int id) {}
};

class DerivedClass: public BaseClass {
public:
    void run(std::string name, unsigned int id) override;
    void runDerived(std::string name, unsigned int id);

    void run_1(std::string name, unsigned int id) {
        printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
    }
    void run_2(std::string name, unsigned int id) {
        printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
    }
};

void DerivedClass::run(std::string name, unsigned int id)
{
    runDerived(name, id);
}

void DerivedClass::runDerived(std::string name, unsigned int id)
{
    const CallbackIdInfomation_t callbackIdInfolist[] = {
        // {1, DerivedClass::run_1},  // 编译报错
        // {2, DerivedClass::run_2},  // 编译报错
        {3, nullptr},
    };
    const int callbackIdInfolistSize = sizeof(callbackIdInfolist) / sizeof(callbackIdInfolist[0]);

    for (int index = 0; index < callbackIdInfolistSize; index++) {
        if (callbackIdInfolist[index].id == id) {
            if (callbackIdInfolist[index].callbackFunc != nullptr) {
                callbackIdInfolist[index].callbackFunc(name, id);
            } else {
                printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
            }
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    BaseClass* baseExample = new DerivedClass;

    baseExample->run("argv_1", 1);
    baseExample->run("argv_2", 2);
    baseExample->run("argv_3", 3);
    baseExample->run("argv_4", 4);

    delete baseExample;

    return 0;
}

总结:
有使用类的情况下,使用C语言风格的回调函数不可以正常编译/运行。

C++风格的回调函数使用

#include <iostream>
#include <string>
#include <functional>

typedef std::function<void(std::string, unsigned int)> CallbackFunc;

typedef struct {
    unsigned int id;
    CallbackFunc callbackFunc;
} CallbackIdInfomation_t;

class BaseClass {
public:
    virtual void run(std::string name, unsigned int id) {}
};

class DerivedClass: public BaseClass {
public:
    void run(std::string name, unsigned int id) override;
    void runDerived(std::string name, unsigned int id);

    void run_1(std::string name, unsigned int id) {
        printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
    }
    void run_2(std::string name, unsigned int id) {
        printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
    }
};

void DerivedClass::run(std::string name, unsigned int id)
{
    runDerived(name, id);
}

void DerivedClass::runDerived(std::string name, unsigned int id)
{
    const CallbackIdInfomation_t callbackIdInfolist[] = {
        {1, [this](std::string lamdaName, unsigned int lamdaId) { run_1(lamdaName, lamdaId); }},
        {2, [this](std::string lamdaName, unsigned int lamdaId) { run_2(lamdaName, lamdaId); }},
        {3, nullptr},
    };
    const int callbackIdInfolistSize = sizeof(callbackIdInfolist) / sizeof(callbackIdInfolist[0]);

    for (int index = 0; index < callbackIdInfolistSize; index++) {
        if (callbackIdInfolist[index].id == id) {
            if (callbackIdInfolist[index].callbackFunc != nullptr) {
                callbackIdInfolist[index].callbackFunc(name, id);
            } else {
                printf("[%s]%s, %d\r\n", __func__, name.c_str(), id);
            }
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    BaseClass* baseExample = new DerivedClass;

    baseExample->run("argv_1", 1);
    baseExample->run("argv_2", 2);
    baseExample->run("argv_3", 3);
    baseExample->run("argv_4", 4);

    delete baseExample;

    return 0;
}

总结:
有使用类的情况下,需要使用STL的function模版 + lamda表达式,才可以正常编译/运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值