函数指针--全局函数指针与类的函数指针
程序员文章站
2022-12-22 17:28:43
函数指针可以将函数功能当成变量,在实际的业务中应用,可以增加模块的灵活性,提高效率。 例如在结构体中存储一个函数指针,就可以根据实际参数来调用对应的功能,实际应用代码就可以通过一个指针变量来控制和调度多个函数功能。 在全局函数指针一般可以显式和隐式的调用指向函数地址的功能,大部分编译器也可以识别出来 ......
函数指针可以将函数功能当成变量,在实际的业务中应用,可以增加模块的灵活性,提高效率。
例如在结构体中存储一个函数指针,就可以根据实际参数来调用对应的功能,实际应用代码就可以通过一个指针变量来控制和调度多个函数功能。
在全局函数指针一般可以显式和隐式的调用指向函数地址的功能,大部分编译器也可以识别出来2种表达式,比如下面都是等效的。
建议是采用显式的表达式,这样可以增加代码的可读性和严谨性。
int Test(int i); int (*pFunc)(int); pFunc = Test; pFunc(1); pFunc = &Test; (*pFunc)(1);
类的this指针:this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象。全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址,也就是说this可以做如下标签:
- 1. this存在于类的所有非静态函数中,相当于每个非静态函数都含有一个指针参数。
- 2. this是一个私有的类指针变量,可以通过它在函数内访问类的其他任何变量。
- 3. this指向被调用函数所在的对象,this的地址与类实例的地址是一样的,不同的实例意味着this指向的地址是不一样的,因为不同的实例有着不同的this。
- 4. 在类的非静态函数中,存在与成员变量同名的name, this->name显式表示该实例的成员变量(包括静态成员变量), name表示该函数的参数变量或局部变量。
- 5. this不可能存在类的静态函数中,因为静态函数要求地址是静态固定的, 所以在静态函数中是无法读取动态的非静态成员变量。
1. 类的静态成员函数采用可以与全局函数指针相同的调用方式进行兼容,但必须加上类域。
2. 类的非静态成员函数与全局函数指针是不兼容的,即使形参与返回类型一致,他们也是不能进行赋值操作的。可以这么理解因为类的非静态成员函数多包括一个this参数。
3. 类的非静态成员函数赋值也是必须加上类域,同时还要显式的加上取地址符或解引用。
下面是全局函数指针与类的函数指针使用参考
#include <stdio.h> #include <stdlib.h> #include <unistd.h>
int Add(int a, int b){ printf("Add\n"); return a + b;}; int Max(int a, int b){ printf("Max\n"); return a > b ? a : b;}; int Min(int a, int b){ printf("Min\n"); return a < b ? a : b;}; class T; /*Pointer to non-static member function*/ typedef int (T::*MFunc)(int, int); /*Pointer to global function*/ typedef int (*GFunc)(int, int); class T { public: MFunc m_ProcessFunc; public: int Max(int a, int b) {printf("T:Max\n");return a > b ? a : b;}; int Min(int a, int b) {printf("T:Min\n");return a < b ? a : b;}; static int Add(int a, int b) {printf("TS:Add\n");return a + b;}; /*Internal interface function,Encapsulate non-static member functions*/ int Result(MFunc fun, int a, int b){ printf("Result--->"); return (this->*fun)(a, b); } int Init(const int &type) { if (type == 1) { m_ProcessFunc = &T::Max; } else if (type == 2) { //m_ProcessFunc = &(this->Min); // error m_ProcessFunc = &T::Min; } else { printf("unkown type\n"); return -1; } return 0; } int Run(int a, int b) { // m_ProcessFunc(a, b); // error (this->*m_ProcessFunc)(a, b); } //static int ExRes(T *t, int a, int b) {printf("ST:Add\n");return (t->*m_ProcessFunc)(a, b);}; }; /*External interface function,Encapsulate non-static member functions*/ int MResult(T* p, MFunc fun, int a, int b) { printf("MResult--->"); return (p->*fun)(a, b); } /*External interface function,Encapsulate global or static member functions*/ int GResult(GFunc fun, int a, int b) { printf("GResult--->"); return (*fun)(a, b); } int main(int argc, char *argv[]) { printf("Pro Start...!\n"); int a = 1; int b = 2; /* 1st way:general and static member funtion */ printf("Test 1st................!\n"); GFunc TFunc1 = Add; //like as TFunc1 = &Add; GFunc TFunc2 = T::Add; TFunc1(a, b); (*TFunc1)(a, b); //like as (*TFunc1)(a, b); (*TFunc2)(a, b); /* 2nd way:non-static member funtion */ printf("Test 2nd................!\n"); T Test1; //Test1.Result(&Test1.Max(), a, b); error //Test1.Result(T::Min, a, b); error Test1.Result(&T::Max, a, b); Test1.Result(&T::Min, a, b); Test1.Init(1); Test1.Run(a, b); Test1.Init(2); Test1.Run(a, b); /* 3th way:external funtion */ printf("Test 3th................!\n"); T T1; //MResult(T1, T1.Max, a, b); error //MResult(&T1, T::Max, a, b); error MResult(&T1, &T::Max, a, b); MResult(&T1, &T::Min, a, b); GResult(TFunc1, a, b); GResult(TFunc2, a, b); printf("All Done!\n"); return (EXIT_SUCCESS); }
输出结果:
root@ubuntu:~/Test/test/ $ a.out Pro Start...! Test 1st................! Add Add TS:Add Test 2nd................! Result--->T:Max Result--->T:Min T:Max T:Min Test 3th................! MResult--->T:Max MResult--->T:Min GResult--->Add GResult--->TS:Add All Done!