C++中的回调函数

文章目录

  • 前言
  • 一、什么是函数指针
  • 二、回调函数的概念和应用
    • 2.1 回调函数的概念
      • 2.1.1 普通回调函数
      • 2.1.2 类成员函数回调


前言

大家好,我是不会编程的程序猿,下面我将分享C++中的一个重要知识点,回调函数的理解和应用。


一、什么是函数指针

指针是一个用来指向内存地址的变量。程序运行时,与程序运行相关的所有变量或函数都需要加载内存,这就决定了程序运行时所有变量或函数都可以用指针来加载。函数是存放在内存代码区域内的,它们同样有地址,因此可以用指针来调用函数,我们把这种指向函数入口地址的指针称为函数指针

int add(int nLeft,int nRight);//定义一个add函数
int (*pf)(int,int);//定义一个函数指针,*pf两侧的括号必须得加,否则会产生歧义
pf = add;//通过给函数指针赋值,使得其指向具体函数。
/*函数指针的应用*/
1.(*pf)(10,20);//函数指针的普通调用,与函数调用无异
2.void func(int nValue,int (*pf)(int,int))//函数指针做参数
3.int (*fuc2(int))(int,int);//函数指针做返回值
//说明:按照有内向外的顺序阅读此声明语句。fuc2有形参列表,则fuc2是一个函数,其形参为fuc2(int),fuc2前面有*,所以fuc2返回一个指针,指针本身也包含形参列表(int,int),因此指针指向函数,该函数的返回值为int.

注意:
1.声明函数指针时,只要函数返回值类型参数个数参数类型等保持一致,就可以声明一个函数指针;
2.函数指针必须用括号括起来(*pf)

实际应用过程中,通常使用宏定义的方式来声明函数指针,示例如下:

typedef void (*FP)(char* s);
void Invoke(char* s);
int main(int argc,char* argv[])
{
    FP fp;      //用宏FP来声明一个函数指针fp
    fp=func;
    fp("Hello World!\n");
    return 0;
}

void func(char* s)
{
    printf(s);
}

二、回调函数的概念和应用

2.1 回调函数的概念

回调函数:就是定义并实现一个函数,然后把这个函数的指针作为参数传给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。简单来说,就是由别人的函数运行期间来回调你实现的函数。

回调函数的机制:
1、定义一个函数(普通函数即可);
2、将此函数的地址注册给调用者;
3、特定的事件或条件发生时,调用者使用函数指针调用回调函数。

2.1.1 普通回调函数

普通回调函数1:

#include  
void printWelcome(int len)  
{  
   printf("welcome -- %d\n", len);  
}    
void printGoodbye(int len)  
{  
   printf("byebye-- %d\n", len);  
}   
void callback(int times, void (* print)(int))  
{  
   int i;  
   for (i = 0; i < times; ++i)  
   {  
       print(i);  
   }  
           printf("\n welcome or byebye !\n");  
}  
void main(void)  
{  
   callback(10, printWelcome);  
   callback(10, printGoodbye);  
} 

普通回调函数2:

#include 
typedef int(*callback)(int,int);
int add(int a,int b,callback p)//宏定义的方式声明函数指针p
{
    return (*p)(a,b);
}
int add(int a,int b)
{
    return a+b;
}
int main(int argc,char *args[])
{
    int res = add(4,2,add);
    printf("%d\n",res);
    return 0;
}

普通回调函数3:

//定义带参回调函数
void PrintfText(char* s) 
{
    printf(s);
}

//定义实现带参回调函数的"调用函数"
void CallPrintfText(void (*callfuct)(char*),char* s)
{
    callfuct(s);
}

//在main函数中实现带参的函数回调
int main(int argc,char* argv[])
{
    CallPrintfText(PrintfText,"Hello World!\n");
    return 0;
}

2.1.2 类成员函数回调

#include   
#include  
using namespace std;  
using namespace std::placeholders;  
typedef std::function<void(int,int)> Fun;  
class B
{  
	public:  
         void call(int a,Fun f)  
         {  
            f(a,2);  
         }  
};     
class Test
{  
    public:  
        void callback(int a,int b)  
        {  
           cout<<a<<"+"<<b<<"="<<a+b<<endl;  
        }  
        void bind()  
        {  
           Fun fun=std::bind(&Test::callback,this,_1,_2);  
            B b;  
            b.call(1,fun);  
        } 
};  
int main()  
{  
    Test test;  
    test.bind();  
    return 0;  
}  

本例中
bind函数
一般常用语法是: newFunction=bind(oldFunction,arg_list);
bind函数返回一个新的函数对象。其中bind第一个参数是oldFunction,它是待绑定的函数名,arg_list是oldFunction的参数列表。注意,这个参数列表是旧函数的参数列表,前面提到,返回的是子函数。我们可以随便给子函数定几个参数,但是肯定不能多于bind所绑定的原函数的参数个数。
举个例子:

//g是一个有两个参数的可调用对象  
auto g=bind(f,a,b,_2,c,_1);  
//其中f是具有5个参数的函数  
//当我们调用g(x,y)时,实际调用的是f(a,b,y,c,x)

上面出现的_1,_2是它的占位符,bind最多可以使用9个占位符。这个占位符命名在std的placeholders中,使用时,要使用using std::placeholders.

function函数
function是一个函数对象的“容器”。
如function fun; fun是一个函数模板,可以接受两个int型参数,并返回一个int型参数。

你可能感兴趣的:(C++基础学习,c++)