またメンバ関数へのポインタで疑問がでました。
まずはコードを示します。(VC++6.0 + WinXPです)
#include <iostream>
using namespace std;
class B {
void(B::*pfn)(); // 同じクラスのメンバ関数へのポインタ
public:
void f() { cout << B::f() << endl; }
void SetFunction() { pfn = &B::f; } // 非static版
static void SetFunctionStatic(B &me){ me.pfn = &f; } // static版
void Execute() { (this->*pfn)(); } // 関数実行
};
int main()
{
B ob;
ob.SetFunction();
ob.Execute();
B::SetFunctionStatic(ob);
ob.Execute();
return 0;
}
やってる事はクラスのメンバ変数に同じクラスのメンバ関数のアドレスをセットして
実行するという物です。
アドレスをセットするのにSetFunction()という関数を使ってますが、
片方はstaticな関数です。(thisポインタないので同じクラスの参照を渡してます)
非static版は { pfn = &f; } とすると
error C2276: '&' : 仮想関数のアドレスを取ろうとしました。
と出て(仮想関数じゃないのに)コンパイルエラーとなりますが、
static版はエラーが出ません。
てっきりこれはC++の仕様だと思ってプログラム組んでしまったのですが、
BCCだとエラーになってしまいました。
C++の仕様はstatic版にもクラススコープ指定が必要なのでしょうか?
あと、こういうのってどこで調べたらいいのでしょう?
プログラミング言語C++という本にのっているのでしょうか。
>非static版は { pfn = &f; } とすると
{ pfn = f; } じゃないの?
どうも違うみたいです。
このページの下の方に以前私が質問した内容でその事にふれています。
実際、BCCだとエラーがでました。
&B::f であれば、BCC5.6.4/VC7.1/GCC3.2 のどれでも受理してくれます。
>&B::f であれば、BCC5.6.4/VC7.1/GCC3.2 のどれでも受理してくれます。
問題はそれが仕様かどうか、じゃないですか?
まぁ、コンパイラ3つも試して全部受理するんだから仕様だと思われますが。
にしても気になりますので…お得意の”召喚”していただけないでしょうか?
ぢゃ小寒、ぢゃなくて召喚。
ISO/IEC 14882:1998 5.3.1 Unary operators 3
A pointer to member is only formed when an explicit & is used and
its operand is a qualified-id not enclosed in parentheses.
つまり、静的関数の中だろうがどこだろうが、メンバ関数へのポインタを取るときには
qualified-id が必要、つまり &B::f としなければならない(括弧でくくってはならない)
誤解があるのは
・各インスタンスごとにメンバ関数が生成されるわけではないから、メンバ関数への
ポインタを取るときには this は不要
・ポインタ経由でメンバ関数を呼び出す場合には、呼び出す先の this が必要。
それは必ずしも今の this と一致していなくても良い。
ってあたりかも。
召喚ありがとうございます。
でも、ということは SetFunctionStatic でも本来はスコープ装飾が必要なんでしょう
か?
#俺もIS欲しいなぁ…
みなさん、ありがとうございます。
・・・プログラム修正します。
クラス名を引数にとる引数付きマクロ定義しようかと思ってますが、
修正箇所、結構あるので憂鬱です。
結局、複数のコンパイラで試してどれかエラーが出たら最大公約数的にプログラム
組むのが無難なのでしょうね。
解決した後であれですが、
> ということは SetFunctionStatic でも本来はスコープ装飾が必要なんでしょう
> か?
必要です。って最初からそう書いているつもりですが。
私が見ている ISO/IEC 14882:1998 は既に obsolete で、
今は 2003 になっています。
んで 14882:2003 は邦訳されていて JIS X 3014:2003 として買えます。
¥16500+TAX
http://www.webstore.jsa.or.jp/webstore/Com/FlowControl.jsp?
lang=jp&bunsyoId=JIS+X+3014%3A2003&dantaiCd=JIS&status=1&pageNo=0
最新規格の邦訳、私も買っちゃお、かな?(高いかも)
あっと、ちなみに JIS X3010:2003 は¥13600+TAXです。
閲覧だけなら http://www.jisc.go.jp/ からも可能です。
X3014 の閲覧はできませんでした、残念。