(1)目的:为了实现两个模块之间的通信(这两个模块没有任何依赖关系)
(2) C语言中的函数指针
int (*a)(int q) = 0; //声明一个函数指针a,初始值设为0 //. //. //. int MyFunction (int q) {} a=MyFunction; //接下来a就具有了MyFunction的功能了 int m= a(12);
(3)C++的函数指针
C++与C语言函数指针区别是指向调用类成员函数
class A{ public: int Mymethod(int q); }; int (A::*k)(int q)=0;//前面要指定特定的类 k=&A::Mymethod; //对k指针的赋值 A a; a.*k(12); //k指针的调用 总的来说C++要用特定的函数指针指向类的成员函数,只能专门为一个类服务
(4)什么是回调
举个例子 在我们数据结构中,经常用到快排函数,然而,通常我们还要在写一个比较函数。 因为我们不知道,比较的这些数是整形的,字符型,浮点数 所以一般是在函数参数列表中列一个回调函数地址,通知调用者 他们要自己准备一个比较大小。排序函数借调用者提供的比较函数来比较大小,借函数指针传递参数,就可以不用管比较的数据类型。 如快排函数qsort() 快排函数有4个参数, 分别是要 数组的索引,数组的长度, 数组的一个单位的字节数 和 比较函数。 其中这个比较函数需要我们自己实现。 然后通过qsort调用它。 上述过程涉及被调用者调用调用者的函数,成为回调。
(5)ns3 回调的机制
API ns3主要提供Callback类API接口来为用户提供服务 (分为两部 1用给定的签名声明回掉的类型 2回调实例化)
—针对静态函数
static double CbOne(double a,double b) { std::out<<"a="<<a<<"b="<<b<<std::endl; return a; } int main(int argc,char *argv[]) { //返回类型 double //第一个参数 double //第二个参数 double Callback<double,double,double> one; //回掉实例化,第一个参数是返回值,第二和第三是参数 one = MakeCallback(&CbOne);//讲回调one,通过API MakeCallback()与相应的函数进行匹配 NS_ASSERT(!one.IsNull());//检查一下回调one是否为空 double retone; retone = one(10.0,20.2);//此时one的功能和CbOne的功能是一样的 }
—针对类成员函数
class Mycb{ public: int CbTwo(double a){ std::out<<"a="<<a<<std::endl; return -5; } } //返回类型 int //参数 double Callback<int,double> two; Mycb cb; //创建一个回调,并让他指向Mycb::CbTwo two = MakeCallback(&Mycb::CbTwo,&cb);//与静态函数差别多一个参数,即实例化的cb的地址 //调用的时候也就是调用cb的CbTwo函数 NS_ASSERT(!two.IsNull());//判断回调two不为空 int retTwo; retTwo = two(10.0); NS_ASSERT(retTwo == -5); return 0; }
—针对Null的回调
Two = MakeNullCallback<int,double>(); //构建空的回调 int retTwo = Two(10.2);
疑惑:现在还没有感觉到空回调的意义所在