クラスのメンバ関数のアドレスの取り方

[戻る]
C++初心者 2004/04/21(水) 15:28:41
またメンバ関数へのポインタで疑問がでました。
まずはコードを示します。(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++という本にのっているのでしょうか。

Jojy 2004/04/21(水) 15:54:05
>非static版は { pfn = &f; } とすると
{ pfn = f; } じゃないの?

C++初心者 2004/04/21(水) 16:19:14
どうも違うみたいです。
このページの下の方に以前私が質問した内容でその事にふれています。
実際、BCCだとエラーがでました。

επιστημη [E-Mail] [HomePage] 2004/04/21(水) 16:25:45
&B::f であれば、BCC5.6.4/VC7.1/GCC3.2 のどれでも受理してくれます。

シャノン 2004/04/22(木) 14:19:43
>&B::f であれば、BCC5.6.4/VC7.1/GCC3.2 のどれでも受理してくれます。
問題はそれが仕様かどうか、じゃないですか?
まぁ、コンパイラ3つも試して全部受理するんだから仕様だと思われますが。
にしても気になりますので…お得意の”召喚”していただけないでしょうか?

tetrapod 2004/04/22(木) 14:44:49
ぢゃ小寒、ぢゃなくて召喚。
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 と一致していなくても良い。
ってあたりかも。

シャノン 2004/04/22(木) 17:06:16
召喚ありがとうございます。
でも、ということは SetFunctionStatic でも本来はスコープ装飾が必要なんでしょう
か?

#俺もIS欲しいなぁ…

C++初心者 2004/04/22(木) 17:20:58
[[解決]]
みなさん、ありがとうございます。

・・・プログラム修正します。
クラス名を引数にとる引数付きマクロ定義しようかと思ってますが、
修正箇所、結構あるので憂鬱です。

結局、複数のコンパイラで試してどれかエラーが出たら最大公約数的にプログラム
組むのが無難なのでしょうね。

tetrapod 2004/04/23(金) 08:41:44
解決した後であれですが、
> ということは 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 の閲覧はできませんでした、残念。

古いスレッドには追加発言できません。