C++看懂并使用-----回调函数

一)回调函数的定义

在 C++ 中,回调函数是一段作为参数传递给其他函数的可执行代码。它允许在一个函数内部的特定点 调用外部定义的函数,以实现更灵活的功能。

回调函数(Callback Function)是一种通过函数指针或函数对象(在 C++ 中)实现的机制。简单来说,它是一段可被作为参数传递给其他函数的代码,并且在适当的时候(由接收该函数的函数决定)被调用。这就像是给别人你的电话号码,然后让他们在需要的时候打给你。
1)通过函数指针实现回调函数;

函数指针是指向函数的指针变量,其定义语法如下:

*返回类型 (指针变量名)(参数列表);

cpp 复制代码
#include <iostream>
// 定义回调函数类型,它接受一个整数参数,返回一个整数
typedef int (*CallbackFunction)(int); 
// 函数,它接收一个回调函数作为参数,并对给定数值进行处理
int processValue(int num, CallbackFunction callback)
 {
    return callback(num);
}
// 具体的回调函数,实现将输入数值加10的功能
int addTen(int num)
 {
    return num + 10;
}
// 另一个具体的回调函数,实现将输入数值乘以2的功能
int multiplyByTwo(int num) {
    return num * 2;
}
int main() 
{
    int originalValue = 5;
    // 使用addTen作为回调函数进行处理
    int result1 = processValue(originalValue, addTen);
    std::cout << "使用addTen回调函数的结果: " << result1 << std::endl;
    // 使用multiplyByTwo作为回调函数进行处理
    int result2 = processValue(originalValue, multiplyByTwo);
    std::cout << "使用multiplyByTwo回调函数的结果: " << result2 << std::endl;
    return 0;
}

在这个示例中:

首先通过typedef定义了CallbackFunction类型,它代表一个函数指针类型,指向接受一个整数参数并返回一个整数的函数。

processValue函数接收一个整数和一个CallbackFunction类型的回调函数作为参数,它在内部调用传入的回调函数对给定数值进行处理,并返回处理后的结果。

addTen和multiplyByTwo是两个具体的回调函数实现,分别完成不同的数值处理逻辑。在main函数中,可以看到将不同的回调函数传递给processValue函数,从而实现不同的处理效果。

2)通过函数对象(仿函数)实现回调函数

函数对象是一个类,它重载了函数调用运算符 operator(),使得类的对象可以像函数一样被调用。例如:

示例二:容器元素处理的回调函数(使用函数对象)

cpp 复制代码
#include <iostream>
#include <vector>
// 函数对象(仿函数)类,用于将容器中的元素翻倍
class DoubleElement 
{
public:
    void operator()(int& element) const 
    {
        element *= 2;
    }
};
// 函数用于遍历容器,并对每个元素调用传入的回调函数进行处理
template <typename Container, typename Functor>
void processContainer(Container& container, Functor functor)
 {
    for (auto& element : container)
     {
        functor(element);
    }
}
int main() 
{
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::cout << "处理前的容器元素: ";
    for (int num : numbers)
     {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    // 使用 DoubleElement 函数对象作为回调函数处理容器元素
    processContainer(numbers, DoubleElement());
    std::cout << "处理后的容器元素: ";
    for (int num : numbers) 
    {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个示例中:

DoubleElement 是一个函数对象类,通过重载 operator() 实现了将传入的整数引用类型的参数翻倍的功能,它可以作为回调函数使用。

processContainer 是一个模板函数,它接收一个容器和一个函数对象作为参数,在函数内部遍历容器中的元素,并调用传入的函数对象对每个元素进行处理。
3)事件处理中的回调函数(使用 std::function)

cpp 复制代码
#include <iostream>
#include <functional>
// 定义一个简单的事件处理器类
class EventHandler 
{
public:
    // 使用 std::function 来存储不同类型的回调函数,这里的回调函数无参数,无返回值
    std::function<void()> onButtonClick;
};
int main() {
    EventHandler handler;
    handler.onButtonClick = []() 
    {
        std::cout << "按钮被点击了!" << std::endl;
    };
    // 模拟按钮点击事件,调用存储的回调函数
    std::cout << "模拟触发按钮点击事件" << std::endl;
    handler.onButtonClick();
    return 0;
}

在这个示例中:

EventHandler 类中定义了 onButtonClick 成员变量,其类型为 std::function<void()>,用于存储在按钮点击时要执行的回调函数。

在 main 函数中,通过 lambda 表达式给 onButtonClick 赋值了一个具体的回调函数实现,当模拟按钮点击事件时,就会调用这个存储的回调函数来处理相应的操作。

这些示例展示了 C++ 回调函数在不同场景下的应用,通过回调函数可以让代码更加灵活、可复用和易于扩展。
4)基于类成员函数的回调函数(使用函数指针到类成员函数)

cpp 复制代码
#include <iostream>
#include <vector>
// 定义一个简单的类
class Calculator 
{
public:
    int add(int a, int b) { return a + b; }
    int subtract(int a, int b) { return a - b; }
};
// 定义回调函数类型,指向Calculator类的成员函数,该成员函数接受两个整数参数,返回一个整数
typedef int (Calculator::*MemberCallback)(int, int); 
// 函数用于调用传入的类成员函数回调进行计算
int performOperation(int a, int b, Calculator& calculator, MemberCallback callback)
 {
    return (calculator.*callback)(a, b);
}
int main() {
    Calculator myCalculator;
    int num1 = 10, num2 = 5;
    // 使用Calculator类的add成员函数作为回调进行计算
    int result1 = performOperation(num1, num2, myCalculator, &Calculator::add);
    std::cout << "使用add成员函数回调的结果: " << result1 << std::endl;
    // 使用Calculator类的subtract成员函数作为回调进行计算
    int result2 = performOperation(num1, num2, myCalculator, &Calculator::subtract);
    std::cout << "使用subtract成员函数回调的结果: " << result2 << std::endl;
    return 0;
}

此示例中:

先定义了Calculator类,包含add和subtract两个成员函数用于简单的算术运算。

通过typedef定义了MemberCallback类型,它是指向Calculator类成员函数的函数指针类型,这类成员函数接受两个整数参数并返回一个整数。

performOperation函数接收两个整数参数、一个Calculator类的对象以及一个MemberCallback类型的回调函数指针,在函数内部通过特定语法(calculator.*callback)(a, b)来调用传入的类成员函数回调进行相应的计算。在main函数中展示了如何使用不同的类成员函数作为回调来执行不同的运算操作。
5)数组元素处理回调函数

cpp 复制代码
#include <iostream>
#include <vector>
// 回调函数类型定义,用于处理数组中的元素,无返回值
typedef void (*ArrayCallback)(int&); 
// 函数用于遍历数组,并对每个元素调用回调函数进行处理
void processArray(std::vector<int>& arr, ArrayCallback callback) 
{
    for (int& element : arr)
     {
        callback(element);
    }
}
// 具体的回调函数,实现将数组元素值加1的功能
void incrementElement(int& num)
 {
    num++;
}
int main()
 {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::cout << "处理前的数组: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    // 使用incrementElement作为回调函数处理数组元素
    processArray(numbers, incrementElement);
    std::cout << "处理后的数组: ";
    for (int num : numbers)
     {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

在这个示例里:

定义了ArrayCallback类型,它指向一个接受整数引用作为参数且返回类型为void的函数,适合用来处理数组元素并修改其值。

processArray函数接收一个整数向量和对应的回调函数作为参数,它遍历向量中的每个元素,并调用回调函数对元素进行处理。

incrementElement是一个具体的回调函数,实现对数组元素值加 1 的功能。在main函数中可以看到调用processArray函数并传入incrementElement回调函数后,数组元素都被相应地修改了。

相关推荐
时光话1 小时前
Lua 第11部分 小插曲:出现频率最高的单词
开发语言·lua
泽02022 小时前
C++入门(缺省参数/函数/引用)
开发语言·c++
Themberfue4 小时前
Redis ⑦-set | Zset
java·开发语言·数据库·redis·sql·缓存
__lost5 小时前
MATLAB画出3d的常见复杂有机分子和矿物的分子结构
开发语言·人工智能·matlab·化学·分子结构
mozun20206 小时前
VS BUG(6) LINK : fatal error LNK1158: 无法运行“rc.exe”
c++·bug·vs·链接器·资源文件
夜夜敲码6 小时前
C语言教程(十八):C 语言共用体详解
c语言·开发语言
大学生亨亨6 小时前
go语言八股文(五)
开发语言·笔记·golang
raoxiaoya6 小时前
同时安装多个版本的golang
开发语言·后端·golang
whoarethenext7 小时前
初始https附带c/c++源码使用curl库调用
服务器·c++·qt·https·curl
cloues break.8 小时前
C++进阶----多态
开发语言·c++