函數指針可以將函數功能當成變量,在實際的業務中應用,可以增加模塊的靈活性,提高效率。
例如在結構體中存儲一個函數指針,就可以根據實際參數來調用對應的功能,實際應用代碼就可以通過一個指針變量來控制和調度多個函數功能。
在全局函數指針一般可以顯式和隱式的調用指向函數地址的功能,大部分編譯器也可以識別出來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!
