http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200406/04060037.txt
こちらを見ていてふと疑問に思ったのですが...
staticなメンバはそのクラスのインスタンスが存在する、しないに関わらす、また存在している
数に関係なく唯一存在するものという認識でいます。
これってメインスレッドとサブスレッドに別々のインスタンスを生成させた場合でも
共有してしまうのでしょうか。
CALLBACK関数とかってメンバにする場合staticにするしかないと思っているのですが、
そういう関数を持ったクラスを別スレッド使いたくなった場合はどうするのでしょう。
CCmdTargetの定義を見てみたのですが、
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
staticでないしCALLBACKでもないんですね。どうやって呼ばれているのかな。
static-member関数は いわゆる普通の関数と同じです。
てゆっか、callbackは普通の関数に適用されるもので、
メンバ関数を指定できないので、普通の関数扱いとするために
staticとするわけ。
επιστημη さん、レスありがとうございます。
やってみろ!とか言われると思いました。(^^ゞ
で、やってみようと思ったのですが、現実的にわざわざそんな事するケース
想像できないなあ。と思いまして、ただCWinThreadもプロシージャ持っているだろうから
どうやっているのか調べています。(が、わからない...(ーー;))
関数って複数のスレッドで同時アクセスしても問題ないんでしょうかね。
何かわかったら報告します。
C++ の言語仕様の中にスレッドなんてありませんから(ないよね?)、
関数を複数のスレッドから呼んではならない、と一概に言うことはできないと思いま
す。
問題があるとすれば、その関数の作り方(中身)によるでしょうね。
> 関数って複数のスレッドで同時アクセスしても問題ないんでしょうかね。
'複数のスレッドで同時アクセスしても問題ない'ように実装します。
結局、staticメンバー関数ってクラス名の名前空間で宣言されている
グローバル関数みたいな物という認識で良いのではないかなと思ってます。
インスタンスの有無とは関係ないわけなのでスレッドのそれぞれにインスタンスが
あっても関係ないわけです。そういう意味で名前空間を利用しているだけと言っている
わけです。
επιστημηさんも言われているように
結局、関数をマルチスレッドを認識して組むかどうかによるので
たとえstaticなクラスメンバーにしたところでマルチスレッドを意識した
つくりでなければ、破綻することになると思います。
認識に誤りがあれば、指摘お願いします。
クラスというスコープに限定している、という意味では
名前空間みたいなモンと解釈しても構わんように思います。
> virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
> staticでないしCALLBACKでもないんですね。どうやって呼ばれているのかな。
LRESULT CALLBACK
AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
がMFCのコールバック関数であり、
そこからhWndに関連付けられたウィンドウを探し出して、
CWnd::WindowProcを呼び出しています。
皆様、レスありがとうございます。
>static-member関数は いわゆる普通の関数と同じです。
この意味がやっと理解できました。
でも更に謎が深まってしまいました。
>問題があるとすれば、その関数の作り方(中身)によるでしょうね。
>複数のスレッドで同時アクセスしても問題ない'ように実装します。
二つのスレッドで、別々のデータベースをソートしている場合って問題になるんですかね。
(データベースは別々でもソート関数は一つ。)
あと、2つのスレッドでひたすら円周率を計算させたりとか。
>インスタンスの有無とは関係ないわけなのでスレッドのそれぞれにインスタンスが
>あっても関係ないわけです。
これだと関数ポインタの説明ができなくなりませんか。
例) UINT SetTimer(UINT nIDEvent, UINT nElapse,
void (CALLBACK* lpfnTimer)(HWND, UINT, UINT, DWORD));
その後、CWndの中にこんなの見つけました。
friend LRESULT AFXAPI AfxCallWndProc(CWnd*, HWND, UINT, WPARAM, LPARAM);
グローバル関数を共有していのかな。それとも全然関係ないのかな。
friendの意味を復習中です。また何かわかったら報告します。
dairygoodsさん、レスありがとうございます。見ないで投稿してしまいました。
>LRESULT CALLBACK
>AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
>
>がMFCのコールバック関数であり、
>そこからhWndに関連付けられたウィンドウを探し出して、
>CWnd::WindowProcを呼び出しています。
この説明は良くわかりました。やはりみんなで共有しているんですね。
よく考えたらCALLBACK関数って自分で呼び出す事はありえないので、
複数スレッドで共有しようが何しようが関係ないですね。
頭混乱してきたので、この辺でやめにします。
皆様、ありがとうございました。
> 二つのスレッドで、別々のデータベースをソートしている場合って問題になるんですかね。
> (データベースは別々でもソート関数は一つ。)
問題になるようなソート関数を実装'できます'