成員變數/函式指標的用法 (轉)

worldblog發表於2007-12-06
成員變數/函式指標的用法 (轉)[@more@]

說明:

這是今天看《thinking in c++》的第10章時作的"筆記",前面也有人
問到關於成員指標的問題,我那時說直接傳入this指標,現在看
了書後有多了一種方法,不過,它的語法有點難計。
 
這下回去可以看看MFC的訊息對映/動態建立是怎麼寫的了,我想也應
該是成員函式指標把

指標是指向一些地址的變數,既可以是資料的地址也可以是函式的地址。C++的
成員指標遵從同樣的原則。困難的是所有的指標需要一個地址,但在類內部沒有地
址;選擇一個類的成員意味著在類中偏移。只有把這個偏移和具體的開始地址
結合,才能得到實際地址。成員指標的語法要求選擇一個物件的同時逆向引用成員
指標。

struct simple { int a ; }
simple  so;
simple* sp = &so;

如果有一個這個結構的指標sp和物件so,如果有一個指標指向一個類物件成員,甚至
假設它代表物件內一定的偏移,將會發生什麼?為了取得指標指向的內容,必須用*號逆向引用。但是,它只是一個物件內的偏移,所以還必須要指定那個物件。因此,*號要和逆向引用的物件結合。

sp->*pm = 47; so.*pm = 47;

定義pm的語法是什麼?其實它像任何一個指標,必須說出它指向什麼型別。並且,在定義中也要使用一個‘*’號。唯一的區別只是必須說出這個成員指標使用什麼類的物件。當然,這是用類名和全域性運算子實現的:

定義成員指標:
int simple::*pm;

定義並初始化成員指標:
int simple::*pm = &simple::a;
因為引用到一個類而非那個類的物件,因而,&simple::a僅可作為成員指標的語法表示。


指向函式的指標定義像下面的形式:int(*fp)(float); (*fp)的圓括號用來迫使
正確判斷定義。沒有圓括號,這個就是一個返回int*值的函式。為了定義和使用一個成員函式的指標,圓括號扮演同樣重要的角色。假設在一個結構內有一個函式:

struct simple2 { int f(float); };

透過給普通函式插入類名和全域性運算子就可以定義一個指向成員函式的指標:
int(simple2::*fp)(float);

初始化:
int(simple2::*fp)(float) = &simple2::f;
&號是可選的;可以用不帶參數列的函式識別符號來表示地址:fp = simple2::f;

使用:
simple2 s2;
int i = (s2.*fp)(1.5);

另一個使用例子
class CB
{
   int f1(){ return 1; }
  int f2(){ return 2; }
  int (CB::*fptr[2])();
public:
  CB() { fptr[0] = CB::f1; fptr[1] = &CB::f2; }
  int sel(int i){ return (this->*fptr[i])(); }
};

在建構函式中,成員指標的初始化似乎被過分地指定了。是否可以這樣寫:
fptr[1] = f2; 因為名字f2在成員函式中出現,是否可以自動地認為在這個類範圍內呢?問題是這不符合成員函式的語法,語法要求編譯器能夠判斷將要進行什麼。當成員函式被逆向引用時,它仍被過分地指定了,this似乎多餘。正如前面所講的,當它被逆向引用時,語法也需要成員指標總是和一個物件繫結在一起。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989077/,如需轉載,請註明出處,否則將追究法律責任。

相關文章