関数ポインタ


	> あ、もしかして"*f"の部分は"f"という変数ではなく"FuncTbl[0][0]"
	> そのものを指してるという事なるのでしょうか。
	(関数型への)ポインタ型のf という変数に関数のアドレスを
	コピーしています。
	> 自前の解釈だと、事前のAというクラスの宣言では"f"というメンバは
	> 無いのに、Execute()の中で(a.*f)という表記がされているのが理解でき
	> ないんです。
	C互換の「ポインタを介しての関数の実行」からこんがらがっているのでしょう。
	まず、メンバという条件をなくして理解してみましょう。
	001: void   someFunc( int a ) {
	002:     cout << "value : " << a << endl;
	003: }
	004: 
	005: typedef void (*FP_t)( int );
	006: 
	007: int main(void) {
	008:     FP_t    ptrFunc;
	009:     ptrFunc  = &someFunc;
	010: 
	011:     (*ptrFunc)( 2 );
	012:     ptrFunc( 2 );
	013: }
	5行目で"関数へのポインタ"という型を定義しています。
	8行目でその"関数へのポインタ"という型の***変数***を宣言しています。
	9行目でその変数にsomeFuncのアドレスを***コピー***しています。
	11,12行目でその関数ポインタを介して、関数そのものを実行しています。
	この11,12行目は実は同じ事をしていますが、なぜ2つの書き方があるか
	というと、Cライクな書き方とC++ライクな書き方です。
	本当は11行目のようにして実行することがC++では正しいのですが、
	Cでは「関数名=関数アドレス」という考え方でしたので、その下位互換を
	保つ為、12行目のような書き方も許されています。
	# 文法的には、12行目が「暗黙のポインタ変換」され11行となります。
	C++では、厳密に 「ポインタ=宣言のアドレス」なわけです。
	まとめ                    関数                                変数
	------------------------+-----------------------------------+-----------
	1)xxxの定義             | 戻り型   関数名(引数) {  ....   } | 型名 変数名
	2)xxxのアドレス         | & 関数名                          | & 変数名
	3)xxxへのポインタ型     | 戻り値   * 関数名(引数)           | *型名
	4)ポインタを介しての実体| *関数名                           | *変数名
	                      C                          C++
	--------------------+---------------------------+-------------------------
	a)関数名            |関数名                     | 関数名
	b)関数の型          |関数名(引数)               | 関数名(引数)
	                    |だが型チェックなしにもでき |
	                    |厳密な意味では存在しない   |
	c)関数のアドレス    |関数名                     | &関数名
	d)関数へのポインタ型|*関数の型                  | *関数の型
	e)関数の実体        |関数名(引数){ ... }        |関数名(引数){ ... }
	g)関数の実行        |関数名( ... )              | 
	(*ptrFunc)とすることによって「ポインタから(関数の)実体を取得」し、
	その実体に(2)という関数呼び出し演算子を作用させることによって
	関数を実行しているわけです。
	つまり、Cで関数アドレス=関数名とおかしな文法を持ち込んでいたのを
	ただしたわけです。
	そして、C++における関数の実行とは関数の実体に関数呼び出し演算子を
	付けたものとなり、「実体の評価」となって、変数と対照が取れるわけです。
	# 評価により、値が確定し、(左辺値でなく)右辺値となります。
	見事に変数との対照が取れ、直行性が出来ています。
	ちなみに、変数に型があるように、関数にも型があり、それは関数名に
	引数リストを付けたものとなっています。
	そう考えると、3)は型名の前に*を付けた物として対照が取れます。
	ここまでの文法が理解できたならば、あとはこれに「クラス」の概念を
	付ける為にスコープ解決演算子"::"とメンバ参照演算子"."を合わせればOKです。
	上記のコードがそのまま
	001: void   SomeClass::someFunc( int a ) {
	002:     cout << "value : " << a << endl;
	003: }
	004: 
	005: typedef void (SomeClass::*FP_t)( int );
	006: 
	007: int main(void) {
	008:     FP_t    ptrFunc;
	009:     ptrFunc  = &SomeClass::someFunc;
	010:     SomeClass    a;
	011:     (a.*ptrFunc)( 2 );
	012: //  a.ptrFunc( 2 );
	013: }
	となります。
	残念ながら、クラスはC++のみの概念なので、クラスメソッドの実行
	(クラスメンバへのアクセス)はC++での表記しかサポートされておらず、
	12行目のような記述は出来ません。
	上記が理解できれば、メンバ関数へのポインタが配列に入っているので、
	> >     Func f = FuncTbl[0][0];
	> 
	> ここで宣言した、Aクラスのメンバ(関数)へのオフセット(ポインタ)です。
	> >     (a.*f)();
	は理解できるのではないでしょうか?