函数指针与回调函数基础

高性能网络服务器开发常采用异步非阻塞IO模型,事件驱动设计中函数指针和回调函数至关重要。本文聚焦函数指针的基础知识,为后续的事件驱动编程打下基础,后续内容将探讨回调函数的运用。
摘要由CSDN通过智能技术生成

在高性能网络服务器程序的开发过程中,我们不能使用同步阻塞,同步非阻塞, 异步阻塞这几种IO模型。这几种IO模型只能应对吞吐量较小或一般的应用。面对巨大吞吐量的应用程序,如大型在线MMOG,游戏服务器,登录服务器等的设 计通常都要采用异步非阻塞IO模型,即事件驱动的设计方法。事件驱动的设计中,函数指针和回调函数是必不可少的编程技术,函数指针是最为基础的知识,本文 先详细描述函数指针的相关知识,打好基础,为后续的开发做好准备。另一篇文章中讨论回调函数。


第一部分   函数指针

函 数指针提供了一些非常有趣,高效和优雅的编程技术。你可以使用它们来替换switch/if语句,以实现自己的延迟绑定或者实现自己的回调函数。但是,需 要付出一些代价,因为函数指针的语法相对复杂。在很多计算机书籍和文档中,对函数指针的描述都停留在表面上。函数指针使用起来不像普通指针那样容易出错, 因为我们不会用函数指针去分配和释放内存。要使用函数指针,我们只需要理解什么是函数指针,熟悉函数指针的语法既可。

什么是函数指针?
         函数指针就是一个指针变量,用来指向函数地址。对于函数地址,我们可能有些陌生,不太容易理解。为此,我们需要明白,正在运行的程序(也叫进程)在内存中 占据一定的空间。进程包括编译好的程序代码和需要使用的变量。于是,程序代码中的函数就是一些字符域,要得到一个函数地址,也就是得到这些字符域的起始地 址。唯一重要的是,你(说编译器或处理器更恰当一些)如何解释指针指向的内存。

下页是用来说明函数指针如何替换if/switch语句要用到的几个例子函数:
// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function  pointer  
float Plus    (float a, float b) { return a+b; }
float Minus    (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }

1. 函数指针的三种形式:
    指向普通C函数的函数指针        --- C语言中的函数指针
    指向C++类静态成员函数的函数指针    --- C++
    指向C++类非静态成员函数的函数指针   --- C++

    前两种函数指针在本质上是一样的,那么,什么是函数指针的本质?指针的本质又是什么?我相信谁都知道,指针的本质就是地址。那么,函数指针的本质自然也就 是函数地址。我们定义函数指针的目的就是要用它来存放某个函数的地址。问题在这里,类成员函数的地址表示和普通C函数的地址是不一样的。要表示一个类例的成员 函数,光有函数地址还不够,因为每个类实例拥有一个非静态成员函数,而每个实例在内存中都要占据一定的空间,所以,非静态类成员函数的地址由两部分组成,一 个是    实例地址,一个是函数地址。实例地址通过隐含的this指针来传递。函数地址就是函数在实例所占内存中的偏移地址,只不过这个地址通过函数名取得,我们不 需要关心其偏移具体是多少.

    静态成员函数和非静态成员函数的区别是,静态成员函数并不是第个实例都拥有一个这样的函数。所以,静态成员函数的地址并不需要实例地址,也就是说,没有this指针。其地址实质上和普通的C函数地址是一样的,只不过在定义函数指针时会有所不同。

    说到这里,几者的区别已经很清楚了。第一种和第三种的区别,两者的区别是:要得到一个类实例的成员函数指向非静态成员函数的函数指针需要一个隐含参数:指向类实例的this指针。而指向普通C函数的函数指针只需要得到函数地址既可。 这两种类型的函数指针是不兼容的,即,不可互相赋值。

    这两种类型的指针分别是怎么定义的呢?
    指向普通函数的指针:
    int (*pt2Function)(float, char, char) = NULL;                       // C

    指向类成员函数的指针:
    int (TMyClass::*pt2Member)(float, char, char) = NULL;               // C++
    int (TMyClass::*pt2ConstMember)(float, char,char) const = NULL;      // C++

    todo : 指向静态成员函数的函数指针定义

2.    调用约定(Calling Convention)
    The calling convention tells the compiler things like how to pass the arguments or how to generate the name of a function. 
    下页是几种调用约定:
    __cdecal : 默认
    __std
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值