コール関数リストの作り方 – プログラミング – Home

コール関数リストの作り方
 
通知
すべてクリア

[解決済] コール関数リストの作り方


こーひ
 こーひ
(@こーひ)
ゲスト
結合: 23年前
投稿: 6
Topic starter  

MFC でウィンドウ内に複数の子ウィンドウを貼り付け、それらの子ウィンドウ内で
さらに複数の子ウィンドウ(孫ウィンドウ)を貼り付けるといった構成のアプリを
作っています。

そこで、ある孫ウィンドウ上のスライダで値を変更すると、いとこにあたる孫ウィ
ンドウのエディットボックスの値が変わるという仕組みをどのように作ったらよい
か分からずに困っています。

ドキュメントクラスにコール関数リストみたいなものを作ったらどうかとも思って
みて、vector<void *> で挑戦したのですが、うまくいきませんでした。

「いとこ」にあたるウィンドウの関数をコールする方法、あるいは
コール関数リストの作り方を教えてもらえないでしょうか。

私が考えたプログラム
-----
ドキュメントクラスにおいて
std::vector<void *> callfunc;
void Call()
{
for (int i = 0; i < callfunc.size(); i++)
(*this)[i](); // <- ここでコンパイルエラーがでます
// error C2064: 関数ポインタとして評価されない式を使って、
// 関数を呼び出そうとしました。
}

ある孫ウィンドウにおいて、
pDoc->callfunc.push_back(<関数名>);

別の孫ウィンドウにおいて、
pDoc->Call();
-----


引用未解決
トピックタグ
YuO
 YuO
(@YuO)
ゲスト
結合: 24年前
投稿: 252
 

根本的な間違いがありますよ。

> (*this)[i](); // <- ここでコンパイルエラーがでます

thisポインタは何を指していますか?
(*this)[i],つまりthis->operator[](i)は正しい呼び出しで,
関数ポインタまたは関数呼び出し演算子を実装したクラスのオブジェクトを返しますか?

あと,void *ではなく,実際の型にしないと呼び出しが面倒です。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> 「いとこ」にあたるウィンドウの関数をコールする方法

ビュークラスにエディットボックスのポインタを
保持しておけばよいのでは?


返信引用
こーひ
 こーひ
(@こーひ)
ゲスト
結合: 23年前
投稿: 6
Topic starter  

YuO さん、dairygoods さん、ご助言ありがとうございます。

ご助言を基にいろいろ考えて、下記の方法で解決しました。
いまのところ、うまくいっているようです。
ありがとうございました。

-----
// ◆CallFuncClass と、そのリストクラスを作る
class CallFunc {
CallFuncClass() {};
~CallFuncClass() {};
virtual void CallFunc() = 0;
};
class CallFuncList: public std::vector<CallFunc *> {
CallFuncList() {};
~CallFuncList() {};
void Call()
{
for (int i = 0; i < size(); i++)
(*this)[i]->CallFunc();
};
};

// ◆ドキュメントクラスでリストを保有
class XXDoc: public CDocument, public CallFuncClass {

CallFuncList cfl;
};

// ◆呼び出される側のクラス
class XXCalledClass: public CallFunc {
virtual BOO OnInitDialog()
{
GetDocument()->cfl.push_back(this);
};
void CallFunc()
{
// 処理したい内容
};
};

// ◆呼び出し側
void CallRoutine()
{
GetDocument()->cfl.Call();
}
-----


返信引用
こーひ
 こーひ
(@こーひ)
ゲスト
結合: 23年前
投稿: 6
Topic starter  

こーひです。
解決したと書いたコードが間違っていましたので、修正します。

正しくは以下です。
-----
// ◆CallFuncClass と、そのリストクラスを作る
class CallFuncClass {
CallFuncClass() {};
~CallFuncClass() {};
virtual void CallFunc() = 0;
};
class CallFuncList: public std::vector<CallFuncClass *> {
CallFuncList() {};
~CallFuncList() {};
void Call()
{
for (int i = 0; i < size(); i++)
(*this)[i]->CallFunc();
};
};

// ◆ドキュメントクラスでリストを保有
class XXDoc: public CDocument {

CallFuncList cfl;
};

// ◆呼び出される側のクラス
class XXCalledClass: public CallFuncClass {
virtual BOO OnInitDialog()
{
GetDocument()->cfl.push_back(this);
};
void CallFunc()
{
// 処理したい内容
};
};

// ◆呼び出し側
void CallRoutine()
{
GetDocument()->cfl.Call();
}
-----


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 24年前
投稿: 252
 

vectorを継承させるのではなく,

// VC++ (6.0およびそれ以前)の制限。
// 標準には戻り値がvoidでも適合
> virtual void CallFunc() = 0;
virutal int CallFunc() = 0;

// ラッパクラスは利用しない
> class XXDoc: public CDocument {
> CallFuncList cfl;
> };
class XXDoc : public CDocument {
typedef std::vector<CallFuncClass *> CallFuncList;
CallFuncList cfl;
};

// 呼び出しはfor_eachとmem_funで処理
> void CallRoutine()
> {
> GetDocument()->cfl.Call();
> }
void CallRoutine (void)
{
CallFuncList & cfl = GetDocument()->cfl;
std::for_each(cfl.begin(), cfl.end(), std::mem_fun(&CalFuncClass::CallFunc));
}
このようにすれば,CallFuncListクラスは不要です。もともと,
> (*this)[i]->CallFunc();
これは,
cfl[i]->CallFunc();
と書けていたわけですから。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました