ページ 1 / 1
あるクラスのメンバ関数を、そのクラスのメンバ変数で保持したい
Posted: 2009年12月29日(火) 18:30
by 3T
お世話になります。
また質問させてください。
http://www.geocities.jp/ky_webid/cpp/language/034.html
このサイトを参考に、メンバ関数をメンバポインタ変数で保持・実行をしたいのですが、上手くいきません。
どのように改善したらいいのでしょうか。
#include <iostream>
class CSample
{
public:
void (CSample::*p)();
void func()
{
printf("func\n");
}
};
int main()
{
CSample obj;
obj.p = &CSample::func;
(obj.*p)();// error C2065: 'p' : 定義されていない識別子です。
return 0;
}
上のソースですと、コメント部分にエラーが発生してしまいます。
これをどうにか出来ないか、という相談です。
よろしくお願いします。
Re:あるクラスのメンバ関数を、そのクラスのメンバ変数で保持したい
Posted: 2009年12月29日(火) 18:37
by たかぎ
これではダメです。
設計の善し悪しは別として...
(obj.*obj.p)();
とする必要があります。
Re:あるクラスのメンバ関数を、そのクラスのメンバ変数で保持したい
Posted: 2009年12月29日(火) 20:46
by 3T
うええ……もう訳が分からない状態です;
確かに、そうすると動作しますが……何でそういう記述になるのかとかが分かりません;;
勉強不足ですね。
また、設計の善し悪しは~ということからして、別の方法を取った方が良いということですかね。
色々勉強してみます。。。
ありがとうございます。
Re:あるクラスのメンバ関数を、そのクラスのメンバ変数で保持したい
Posted: 2009年12月29日(火) 21:50
by sizuma
>メンバ関数ポインタ pFunc を定義したとき、どのインスタンスのものかを指定しないため、「pFunc()」と書くだけでは、どのインスタンスのメンバ関数を呼び出すのか分かりません。そのため、インスタンス名と上記の2つの演算子のいずれかを使ってアクセスすることになります。
参考にされてるサイトにこう書いてありますね。
つまり、
「*obj.pだけだと、ここにCSampleのfunc関数ポインタがあるのはわかるんだけど、どのインスタンスのポインタなのかが分からない。objかな?obj2かな(生成すれば)?」
ということなのでしょう。
staticメソッドだとクラス固有だから指定はいりません。
Javaだと確か指定しても指定しなくてもアクセス出来た気が・・・・(staticメソッドに)
オーバーライドされてなきゃ(virtualついてなきゃ)問題ない気もしますけどねー
例えば普通にmainから関数ポインタ呼び出すことを考えてみると、インスタンスを生成してないのにメンバ関数を呼び出しちゃいけないですよね?
クラスはただの鋳型で、実体(インスタンス)はそれぞれ別の物だから、指定するのが当然なわけです。
と、分かってる風に書いてるけど、C++入門者です
間違ってたらたかぎさんが訂正してくれるはず^^;

Re:あるクラスのメンバ関数を、そのクラスのメンバ変数で保持したい
Posted: 2009年12月29日(火) 22:10
by 3T
なるほど、そういうことは考えられますね……。
それで、こんな変な(といったら失礼ですが)書き方してるわけですね。
ありがとうございます。
Re:あるクラスのメンバ関数を、そのクラスのメンバ変数で保持したい
Posted: 2009年12月29日(火) 22:53
by sizuma
>それで、こんな変な(といったら失礼ですが)書き方してるわけですね。
ごく自然な表現だと思いますよ?
まぁ感じ方は人それぞれでしょうけど・・・
>メンバ関数をメンバポインタ変数で保持・実行をしたい
なにを実装したいのか分からないので、はっきりとはいえませんが。
とりあえず、変数はprivateにして、メソッドからアクセスさせたほうがいいと思います。
そうすれば、obj.*obj.pみたいな表現はなくなりますから。
せっかくオブジェクト指向の機能があるので、基本的に変数は隠蔽ですね。