C 成員函式指標的應用

2021-09-09 03:15:01 字數 3204 閱讀 1288

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;pmf 

=  

& a::strcpy; 

有些老的編譯器可以通過沒有&號的賦值方式,但標準c++強制要求加上&號。 

使用型別定義

c++新標準規定了一種新的方法,使用別名宣告來定義型別的別名:

using si=sales_item; //si是sales_item的同義詞

這種使用關鍵字using作為別名宣告的開始,其後緊跟別名和等號,其作用是把等號左側的名字規定成等號右側型別的別名。

型別別名和型別的名字等價,只要是型別的名字能出現的地方,就能使用型別別名。

eg: si item;  //等價於sales_item item;

可以用型別定義來隱藏複雜的成員指標語法。例如,下面的語句定義了pma是乙個指向a成員函式的指標,函式返回無型別值,函式引數型別為char * 和 const char *: 

typedef void(a::*pma)(char *, const char *); 

using pma=void (a::*)(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*))

// 或用a的指標表達方式指向成員指標:

void

dispatcher(a 

*  p, 

void

(a::

* pmf)(

char*, 

const

char*))

// 函式的呼叫方法為:

dispatcher(a, pmf); 

//.* 方式

dispatcher(

& a, pmf); 

//->* 方式 

高階使用技巧 

以上是成員函式的基本知識。現在介紹它的高階使用技巧。 

成員指標陣列

在下例,宣告了乙個含有二個成員指標的陣列,並分配類的成員函式位址給成員指標: 

pma pmf[2]= ; 

也就是void (a::*pma[2])(char *, const char *)= ; 

這樣的陣列在選單驅動應用中很有用。選擇選單項後,應用將呼叫相應的回叫函式,如下所示: 

enum

menu_options ;

int  main()} 

const 型別的成員函式

成員指標的型別應該與成員函式型別一致。上面例子中的pmf 可以指向a的任意函式,只要該函式不是const型別。如下所示,如果將touppercase()的位址分配給pmf,將導致編譯出錯,因為touppercase() 的型別是const。 

class a

;pmf

=&a::touppercase; 

//出錯,型別不匹配

// 解決的方法是宣告乙個const型別的成員指標:

void

(a::pcmf)(

char*, 

const

char*) 

const

;pcmf

=&a::touppercase; 

//現在可以了 

有些差勁的編譯器允許乙個非const型別的成員指標指向const型別的成員函式。這在標準c++是不允許的。

C 成員函式指標的應用

原文出處 c 中,成員指標是最為複雜的語法結構。但在事件驅動和多執行緒應用中被廣泛用於呼叫回叫函式。在多執行緒應用中,每個執行緒都通過指向成員函式的指標來呼叫該函式。在這樣的應用中,如果不用成員指標,程式設計是非常困難的。剛遇到這種語法時也許會讓你止步不前。但你會發現,使用恰當的型別定義之後,複雜的...

C 成員函式指標的應用

c 中,成員指標是最為複雜的語法結構。但在事件驅動和多執行緒應用中被廣泛用於呼叫回叫函式。在多執行緒應用中,每個執行緒都通過指向成員函式的指標來呼叫該函式。在這樣的應用中,如果不用成員指標,程式設計是非常困難的。剛遇到這種語法時也許會讓你止步不前。但你會發現,使用恰當的型別定義之後,複雜的語法是可以...

C 成員函式指標的應用

原文 c 中,成員指標是最為複雜的語法結構。但在事件驅動和多執行緒應用中被廣泛用於呼叫回叫函式。在多執行緒應用中,每個執行緒都通過指向成員函式的指標來呼叫該函式。在這樣的應用中,如果不用成員指標,程式設計是非常困難的。剛遇到這種語法時也許會讓你止步不前。但你會發現,使用恰當的型別定義之後,複雜的語法...