声明函数指针并实现回调
当前位置:以往代写 > C/C++ 教程 >声明函数指针并实现回调
2019-06-13

声明函数指针并实现回调

声明函数指针并实现回调

副标题#e#

措施员经常需要实现回调。本文将接头函数指针的根基原则并说明如何利用函数指针实现回调。留意这里针对的是普通的函数,不包罗完全依赖于差异语法和语义法则的类成员函数(类成员指针将在另文中接头)。

声明函数指针

回调函数是一个措施员不能显式挪用的函数;通过将回调函数的地点传给挪用者从而实现挪用。要实现回调,必需首先界说函数指针。尽量界说的语法有点不行思议,但假如你熟悉函数声明的一般要领,便会发明函数指针的声明与函数声明很是雷同。请看下面的例子:

void f();// 函数原型

上面的语句声明白一个函数,没有输入参数并返回void。那么函数指针的声明要领如下:

void (*) ();

让我们来阐明一下,左边圆括弧中的星号是函数指针声明的要害。别的两个元素是函数的返回范例(void)和由边圆括弧中的进口参数(本例中参数是空)。留意本例中还没有建设指针变量-只是声明白变量范例。今朝可以用这个变量范例来建设范例界说名及用sizeof表达式得到函数指针的巨细:

// 得到函数指针的巨细

unsigned psize = sizeof (void (*) ());

// 为函数指针声明范例界说

typedef void (*pfv) ();

pfv是一个函数指针,它指向的函数没有输入参数,返回类行为void。利用这个范例界说名可以埋没巨大的函数指针语法。

指针变量应该有一个变量名:

void (*p) (); //p是指向某函数的指针

p是指向某函数的指针,该函数无输入参数,返回值的范例为void。左边圆括弧里星号后的就是指针变量名。有了指针变量便可以赋值,值的内容是署名匹配的函数名和返回范例。譬喻:

void func()

{

/* do something */

}

p = func;

p的赋值可以差异,但必然要是函数的地点,而且署名和返回范例沟通。

通报回调函数的地点给挪用者

此刻可以将p通报给另一个函数(挪用者)- caller(),它将挪用p指向的函数,而此函数名是未知的:

void caller(void(*ptr)())

{

ptr(); /* 挪用ptr指向的函数 */

}

void func();

int main()

{

p = func;

caller(p); /* 通报函数地点到挪用者 */

}

假如赋了差异的值给p(差异函数地点),那么挪用者将挪用差异地点的函数。赋值可以产生在运行时,这样使你能实现动态绑定。


#p#副标题#e#

挪用类型

到今朝为止,我们只接头了函数指针及回调而没有去留意ANSI C/C++的编译器类型。很多编译器有几种挪用类型。如在Visual C++中,可以在函数范例前加_cdecl,_stdcall可能_pascal来暗示其挪用类型(默认为_cdecl)。C++ Builder也支持_fastcall挪用类型。挪用类型影响编译器发生的给定函数名,参数通报的顺序(从右到左或从左到右),仓库清理责任(挪用者可能被挪用者)以及参数通报机制(仓库,CPU寄存器等)。

将挪用类型当作是函数范例的一部门是很重要的;不能用不兼容的挪用类型将地点赋值给函数指针。譬喻:

// 被挪用函数是以int为参数,以int为返回值

__stdcall int callee(int);

// 挪用函数以函数指针为参数

void caller( __cdecl int(*ptr)(int));

// 在p中诡计存储被挪用函数地点的犯科操纵

__cdecl int(*p)(int) = callee; // 堕落

指针p和callee()的范例不兼容,因为它们有差异的挪用类型。因此不能将被挪用者的地点赋值给指针p,尽量两者有沟通的返回值和参数列。

    关键字:

在线提交作业