ページ 11

クラス内のメンバ関数ポインタを外から呼び出したい

Posted: 2012年7月25日(水) 00:18
by YYSS
メンバ関数ポインタをクラス外から呼びたいのですがエラーになってしまいます。

クラス定義

コード:

class C_test{

private:
	int		m_Count;	//	制御カウント
	
public:
	void	(C_test::*ScreenEvent)();		//	ここに差し替える
	void	NoEvent(){}				//	何もしないときはこいつをいれとく
};
呼ぶとき

コード:

	( LineMaster->*ScreenEvent )();		//	エラー 「定義されていない識別子です。」
	LineMaster->ScreenEvent();		//	エラー 「0 引数を取り込む関数には評価されません。」
調べたところ関数ポインタは、->*、で呼べるというのが分かったのですが、何故エラーになるのかが分かりません。

クラス内なら

コード:

	(this->*ScreenEvent)()		//	エラーなし
で問題なく呼べるのですが、クラス外から呼ぶ場合は、どういう表記にすればいいのでしょうか?

Re: クラス内のメンバ関数ポインタを外から呼び出したい

Posted: 2012年7月25日(水) 00:23
by softya(ソフト屋)
そういう設計はしないほうが良いと思いますが。
なぜ、そんな設計にする必要があるかを説明してもらえますか?

Re: クラス内のメンバ関数ポインタを外から呼び出したい

Posted: 2012年7月25日(水) 00:37
by YYSS
softya(ソフト屋) さんが書きました:そういう設計はしないほうが良いと思いますが。
なぜ、そんな設計にする必要があるかを説明してもらえますか?
ループ内で処理を行う際に、関数ポインタを使えば処理を分岐させる必要が無く、
関数ポインタの中身?関数?を差し替えるだけで処理を変えれるのでスマートになると思っていたのですが・・・

イメージ

コード:

	//分岐が増えると管理しづらい
	switch( select ){
	case 0:	fanc1();
	case 1:	fanc2();
	case 2:	fanc3();
	case 3:	fanc4();
	case 4:	fanc5();
	}

	//理想
	(this->*FancBase)();
	//FancBaseの中身を差し替えるだけで処理を変えれる
1行で済むので、管理がしやすいという思想です。
こういう設計は問題なのでしょうか?

Re: クラス内のメンバ関数ポインタを外から呼び出したい

Posted: 2012年7月25日(水) 00:57
by softya(ソフト屋)
外部に公開しているのが問題でしょうね。
外部から直接呼び出せて良いんでしょうか?

(this->*ScreenEvent)()で呼び出すだけのメンバ関数を用意してはどうでしょうか?
あと関数の切り替えも出来れば隠蔽したい所ですが、そこもenum名のswitch文は避けたい所ですね。
ScreenEventの内容を切り替えるだけのメンバ関数も用意したほうが良いでしょうね。面倒ですが。
そすればpublicな関数はすごく減らせると思います。

Re: クラス内のメンバ関数ポインタを外から呼び出したい

Posted: 2012年7月25日(水) 05:38
by へにっくす
YYSS さんが書きました:クラス外から呼ぶ場合は、どういう表記にすればいいのでしょうか?
以下にその説明があります。

ロベールのC++教室
第57章 メンバ関数ポインタ天国


しかし管理しやすいか?と言うと、そうでもないと思いますけどね。

Re: クラス内のメンバ関数ポインタを外から呼び出したい

Posted: 2012年7月25日(水) 23:35
by YYSS
へにっくす さんが書きました: しかし管理しやすいか?と言うと、そうでもないと思いますけどね。
そうですね、思い直すと余計ややこしくなってる気がしないでもないです;;
softya(ソフト屋) さんが書きました:外部に公開しているのが問題でしょうね。
外部から直接呼び出せて良いんでしょうか?

(this->*ScreenEvent)()で呼び出すだけのメンバ関数を用意してはどうでしょうか?
あと関数の切り替えも出来れば隠蔽したい所ですが、そこもenum名のswitch文は避けたい所ですね。
ScreenEventの内容を切り替えるだけのメンバ関数も用意したほうが良いでしょうね。面倒ですが。
そすればpublicな関数はすごく減らせると思います。
メンバ変数はPrivate、メンバ関数はPublicという、変な常識に囚われていました;;
PriveteとPublicの関数をうまく分けて、Publicな関数をスッキリさせたいと思います。


お二方とも、返答ありがとうございました。