c++中,成員指標是最為複雜的語法結構。但在事件驅動和多執行緒應用中被廣泛用於呼叫回叫函式。在多執行緒應用中,每個執行緒都通過指向成員函式的指標來呼叫該函式。在這樣的應用中,如果不用成員指標,程式設計是非常困難的。
剛遇到這種語法時也許會讓你止步不前。但你會發現,使用恰當的型別定義之後,複雜的語法是可以簡化的。本文引導你了解成員函式指標的宣告,賦值和呼叫回叫函式。
成員函式指標的宣告
乙個成員函式指標包括成員函式的返回型別,後隨::操作符類名,指標名和函式的引數。初看上去,語法有點複雜。其實可以把它理解為乙個指向原函式的指標,格式是:函式返回型別,類名,::操作符,指標星號,指標名,函式引數。
乙個指向外部函式的指標宣告為:
void (*pf)(char *, const char *);
void strcpy(char * dest, const char * source);
pf=strcpy;
乙個指向類a成員函式的指標宣告為:
void (a::*pmf)(char *, const char *);
宣告的解釋是:pmf是乙個指向a成員函式的指標,返回無型別值,函式帶有二個引數,引數的型別分別是char * 和 const char *。除了在星號前增加a:: ,與宣告外部函式指標的方法一樣。
賦值 給成員指標賦值的方法是將函式名通過指標符號&賦予指標名。如下所示:
class a
public:
void strcpy(char *, const char *);
void strcat(char *, const char *);
pmf = &a::strcpy;
有些老的編譯器可以通過沒有&號的賦值方式,但標準c++強制要求加上&號。
使用型別定義
可以用型別定義來隱藏複雜的成員指標語法。例如,下面的語句定義了pma是乙個指向a成員函式的指標,函式返回無型別值,函式引數型別為char * 和 const char *:
typedef void(a::*pma)(char *, const char *);
pma pmf= &a::strcat; // pmf是pmf型別(類a成員指標)的變數
下文會看到使用型別定義特別有利於宣告成員指標陣列。
通過成員指標呼叫成員函式
可以在不必知道函式名的情況下,通過成員指標呼叫物件的成員函式。例如,函式dispatcher有乙個變數pmf,通過它呼叫類成員函式,不 管它呼叫的是strcpy()函式還是strcat()函式。指向外部原函式的指標和指向類成員函式的指標是有很大區別的。後者必須指向被調函式的宿主對 象。因此,除了要有成員指標外,還要有合法物件或物件指標。
現舉例做進一步說明。假設a有二個例項,成員函式指標支援多型性。這樣在成員指標呼叫虛成員函式時是動態處理的(即所謂後聯編 - 譯註)。注意,不可呼叫構造和析構函式。示例如下:
a a1, a2;
a *p= &a1; //建立指向a的指標
//建立指向成員的指標並初始化
void (a::*pmf)(char *, const char *) = &a::strcpy;
//要將成員函式繫結到pmf,必須定義呼叫的物件。
//可以用*號引導:
void dispatcher(a a, void (a::*pmf)(char *, const char *))
char str[4];
(a.*pmf)(str, 「abc」); //將成員函式繫結到pmf
//或用a的指標表達方式指向成員指標:
void dispatcher(a * p, void (a::*pmf)(char *, const char *))
char str[4]; (p->*pmf)(str, 「abc」);
//函式的呼叫方法為:
dispatcher(a, pmf); // .* 方式
dispatcher(&a, pmf); // ->* 方式
高階使用技巧
以上是成員函式的基本知識。現在介紹它的高階使用技巧。
成員指標陣列
pma pmf[2]= ;
這樣的陣列在選單驅動應用中很有用。選擇選單項後,應用將呼叫相應的回叫函式,如下所示:
enum menu_options ;
int main()
menu_options option; char str[4];
//從外部資源讀取選項
switch (option)
case copy:
(pa->*pmf[copy])(str, 「abc」);
break;
case concat:
(pa->*pmf[concat])(str, 「abc」);
break;
const 型別的成員函式
成員指標的型別應該與成員函式型別一致。上面例子中的pmf 可以指向a的任意函式,只要該函式不是const型別。如下所示,如果將touppercase()的位址分配給pmf,將導致編譯出錯,因為touppercase() 的型別是const。
class a
public:
void strpcy(char *, const char *);
void strcat(char *, const char *);
void touppercase(char *, const char*) const;
pmf=&a::touppercase; //出錯,型別不匹配
//解決的方法是宣告乙個const型別的成員指標:
void (a::pcmf)(char *, const char *) const;
pcmf=&a::touppercase; // 現在可以了
有些差勁的編譯器允許乙個非const型別的成員指標指向const型別的成員函式。這在標準c++是不允許的。
結語
可能有點費解:成員指標不是真正的指標。傳統意義上的指標是乙個整數,儲存指向某個變數或函式的位址。成員指標則是乙個復合資料結構,包含有若 幹個資料成員。成員指標的這個複雜性使得入門比較困難。然而,一旦掌握了它的語法,就能感到它是在事件驅動和多執行緒應用中呼叫回叫函式必不可少的工具。
指標的指標的用法
直接上 用途 使用乙個函式動態申請記憶體,並賦值。跳出呼叫函式後輸出賦值內容 cpp include include typedef struct data data void fun data p int main void fun data p 我建議你直接執行看看結果,你會發現執行出錯,在這裡...
this指標的用法
1.this指標的用處 乙個物件的this指標並不是物件本身的一部分,不會影響sizeof 物件 的結果。this作用域是在類內部,當在類的非靜態成員函式中訪問類的非靜態成員的時候,編譯器會自動將物件本身的位址作為乙個隱含引數傳遞給函式。也就是說,即使你沒有寫上this指標,編譯器在編譯的時候也是加...
指標的用法
20160728 include include if 0 int sum int int int main int sum int a,int b endif if 0 int main int p a printf d n p p 1 和 的優先順序一樣的所以執行順序一樣從右到左 printf ...