区分回调函数机制与注册函数机制。

一、回调函数机制

/* 
 * 1.回调函数机制的出现:最初,编程时需要调用某个库函数,但是被调用的库函数的某个输入参数是一个函数指针,即指向其他函数的指针,这个其他函数通函数中一般没有,而是需要编程者自己编写。这样本来编程者要调用库函数,而库函数又要返回过来调用编程者自己的一个函数,这就构成了回调函数机制。
 * 2.著名的回调函数机制的实现:是C/C++标准库stdlib.h/cstdlib中的快速排序函数qsort和二分查找函数bsearch中,两者都需要一个比较函数作为输入参数,来比较两个变量的大小来辅助实现排序与查找。
 * void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));
 * void *bsearch(const void *key, const void *base, size_t nelem, size_t width, int(*fcmp)(const void *, const void *));
 * 3.回调函数机制的本质:回调函数机制的本质是,某个函数(以下称本体函数)的某个输入参数是个函数指针,因而可以将其他函数(即回调函数)的功能作为本体函数的一部分。
 * 4.回调函数的设计目的:本体函数的运行功能中有一部分是可替换的,即通过回调函数实现。这样,可让本体函数的核心功能有多种实现方式,从而实现了本体函数的多态化运行,以适应不同的需求情况。
 */


#include <stdio.h>


/*******************************************************
 * 本体函数:calculate().
 ******************************************************/
int calculate( int(* callback_func)(int,int), int a, int b )
{
    int tmp0;
    tmp0=callback_func(a,b);

    int tmp1;
    tmp1=tmp0+10000;

    return tmp1;
}


/**************************************************
 * 四个回调函数:add(), sub(), multiply(), divide().
 *************************************************/
int add(int a, int b)
{
    return a+b;
}

int sub(int a, int b)
{
    return a-b;
}

int multiply(int a, int b)
{
    return a*b;
}

int divide(int a, int b)
{
    return a/b;
}


/********************************************
 * 主函数main()
 ********************************************/
int main()
{
    int result;

    result=calculate(add, 10, 5);
    printf("The result is :%d.\n\n", result);

    result=calculate(sub, 10, 5);
    printf("The result is :%d.\n\n", result);

    result=calculate(multiply, 10, 5);
    printf("The result is :%d.\n\n", result);

    result=calculate(divide, 10, 5);
    printf("The result is :%d.\n\n", result);

    return 0;
}

二、注册函数机制

/*
 * 1.注册函数机制的出现:现在(公元2024年)的大型程序开发,一般都是由一些公司开发出通用的框架程序,而后其他开发者(开发公司)在这些框架程序上进行二次开发。在设计程序框架时,通用框架功能之外的具体功能是要留给框架程序应用者去二次开发实现的,但是这种二次开发要在框架程序的控制范围之内,实现的方法就是留下具体功能的函数指针型变量接口,而不具体实现功能函数,另外提供一种注册函数给二次开发者,来将新开发的函数注册(赋值)给框架程序预留的函数指针型变量接口。
 * 2.著名的注册函数机制的实现:微软的MFC程序开发中的消息处理函数,如按键消息处理函数OnKeyDown(),鼠标消息处理函数OnLButtonDown()、OnRButtonUp()和OnMouseMove()等都是要求二次开发重写的。
 * 3.注册函数机制的本质:注册函数机制的本质是,前面的开发中预先留下一个函数指针型全局变量,作为后期开发的接口函数(或称函数接口、本体函数接口)。后期开发出具体的功能函数后,通过前期开发提供的注册函数将后期开发的函数名(即函数指针)赋值给前期开发预留的函数指针型全局变量,即实现了前期开发预留的接口函数。
 * 4.注册函数的设计目的:为二次开发者预留函数接口,由二次开发者具体实现特定的二次开发功能。
 */


#include <stdio.h>


/***********************************************
 * 本体函数接口(接口函数、函数接口)类型定义。
 ***********************************************/
typedef int(* calculate_func)(int, int);


/************************************************
 * 本体函数接口(接口函数、函数接口),即全局变量定义。
 ************************************************/
calculate_func calculate;


/*******************************************************
 * 注册函数:register_func().
 ******************************************************/
int register_func(calculate_func func)
{
    calculate=func;

    return 0;
}


/**************************************************
 * 四个被注册函数:add(), sub(), multiply(), divide().
 *************************************************/
int add(int a, int b)
{
    return a+b;
}

int sub(int a, int b)
{
    return a-b;
}

int multiply(int a, int b)
{
    return a*b;
}

int divide(int a, int b)
{
    return a/b;
}


/********************************************
 * 主函数main()
 ********************************************/
int main()
{
    int result;

    register_func(add);
    result=calculate(10, 5);
    printf("The result is :%d.\n\n", result);

    register_func(sub);
    result=calculate(10, 5);
    printf("The result is :%d.\n\n", result);

    register_func(multiply);
    result=calculate(10, 5);
    printf("The result is :%d.\n\n", result);

    register_func(divide);
    result=calculate(10, 5);
    printf("The result is :%d.\n\n", result);

    return 0;
}

三、 回调函数机制与注册函数机制的区别:
 *      (1)很多文章混淆了回调函数机制与注册函数机制,两者是两种不同的待定函数设计机制/设计思想。
 *      (2)回调函数机制的设计目的是为了实现本体函数中部分功能的可替换。回调函数机制中的本体函数已经实现了一部分功能。
 *      (3)注册函数机制的设计目的是为了实现本体函数的完全替换。事实上注册函数机制的本体函数完全未实现,是函数定义(声明)与函数实现的彻底分离。
 *      (4)回调函数机制的实现比较简单。包括:
 *              A.设计本体函数(一个参数为回调函数型函数指针,其他参数与回调函数的输入参数相同)。
 *              B.设计回调函数(一般有多个)。
 *              C.调用本体函数(参数为回调函数,及回调函数的输入参数)。
 *      (5)注册函数机制的实现要复杂一些。包括:
 *              A.定义本体函数类型
 *              B.声明本体函数型全局变量,即声明(定义)本体函数。
 *              C.设计注册函数,
 *              D.设计被注册函数(一般有多个)。
 *              E.注册:即调用注册函数将某个被注册函数名(即函数指针)赋值给本体函数型全局变量。
 *              F.调用本体函数(通过上面的本体函数型全局变量实现调用)。
 四、回调函数机制与注册函数机制的相似之处:(注意,只是相似,不是说二者有联系。正因为相似,所以导致两种机制的混淆)
 *      (1)回调函数与被注册函数的形式都是预先固定好的,都要求后续开发者必须事先了解、并严格遵守预定的函数接口形式。
 *      (2)都实现了本体函数的多态化。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C#中,委托和事件都是用于实现回调函数机制。委托是一种类型,它可以存储对一个或多个方法的引用,而事件则是委托的一种特殊用法,它只能用于触发事件时调用方法。 回调函数是一种编程模式,它允许我们将一个函数作为参数传递给另一个函数,并在需要时调用该函数回调函数通常用于异步编程中,例如在网络编程中,当数据到达时,我们可以使用回调函数来处理数据。 委托和事件都可以用于实现回调函数机制。委托可以将一个方法作为参数传递给另一个方法,并在需要时调用该方法。事件则是一种特殊的委托,它只能用于触发事件时调用方法。 使用回调函数的步骤如下: 1. 定义一个委托类型,该委托类型定义了回调函数的签名。 2. 在需要使用回调函数的方法中,将该委托类型的实例作为参数传递给另一个方法。 3. 在另一个方法中,将该委托类型的实例保存下来,并在需要时调用该委托实例。 下面是一个简单的示例代码: ``` // 定义一个委托类型 delegate void MyCallback(int result); class MyClass { // 定义一个方法,该方法接受一个回调函数作为参数 public void DoSomethingAsync(int arg, MyCallback callback) { // 异步执行一些操作 int result = arg * 2; // 调用回调函数 callback(result); } } class Program { static void Main(string[] args) { MyClass obj = new MyClass(); // 创建一个委托实例,该委托实例引用了一个方法 MyCallback callback = new MyCallback(MyCallbackFunction); // 调用DoSomethingAsync方法,并传递委托实例作为回调函数 obj.DoSomethingAsync(10, callback); } // 定义一个回调函数 static void MyCallbackFunction(int result) { Console.WriteLine("Result: " + result); } } ``` 在上面的示例代码中,我们定义了一个委托类型`MyCallback`,它定义了一个接受一个整数参数的回调函数。然后我们定义了一个类`MyClass`,它有一个方法`DoSomethingAsync`,该方法接受一个整数参数和一个回调函数作为参数。在`DoSomethingAsync`方法中,我们异步执行一些操作,并在完成后调用回调函数。在`Main`方法中,我们创建了一个委托实例,并将其作为回调函数传递给`DoSomethingAsync`方法。最后,在回调函数`MyCallbackFunction`中,我们输出了结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值