C++制御系のシステムは巨大クラスになる?

このQ&Aのポイント
  • C++制御系のシステムを作る際、イベントを集中管理する制御用クラスを作る関係について。
  • クラス分割する案と巨大クラスにする案の比較。
  • 後者の案を採用しても各クラスを持つ必要があり、保持クラス数は巨大なままになるか。
回答を見る
  • ベストアンサー

【C++】制御系のシステムは巨大クラスになる??

(1)ユーザ操作起因の「画面上の操作」(リストボックスの選択なり、ボタンのクリックなり) と、 (2)非ユーザ操作  (デバイスからのコールバックや、   マルチキャストでPUSH通信されたデータの受取のコールバック等の処理) が混在するシステムを作る際、 それぞれのイベントを集中管理するための、制御用クラスを作る関係なのか、 巨大なクラスになるのはよくあることなのでしょうか? /----------------------------------------------------/ 以下のようにクラス分割する案は可能でしょうか? 巨大クラスにする案と、分割案では、どちらを採用することが多いでしょうか? (1)-(1)画面Aのイベント通知クラス (1)-(2)画面Bのイベント通知クラス :  画面Cの・・・ : (2)-(1)非画面のイベントXの通知クラス (2)-(2)非画面のイベントYの通知クラス : : (3)各イベントの通知を受け、次にどんな処理をするか?を振り分けるクラス (4)-(1)画面Aの処理を実行するクラス (4)-(2)画面Bの処理を実行するクラス :  画面Cの・・・ : (5)-(1)非画面系Xの処理を実行するクラス (5)-(2)非画面系Yの処理を実行するクラス /----------------------------------------------------/ また、後者の案を採用しても、 「(3)各イベントの通知を受け、次にどんな処理をするか?を振り分けるクラス」 は、コーディング行数的には、小さく分割はされても、 「(3)」は、各クラスを持っていなければ、処理の委譲ができないため、       (3)       ↑    ________   |  |  |  |   (1)  (2)  (4)  (5) のような構造にならざるを得ず、 「コーディング行数」は分割できても 「保持クラス数」は巨大なままにならざるを得ないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

単に、「同じような発生の仕方をするイベントの種類が多い」だけじゃないのかと思いますが? 普通、「自分は何者なのか?」or「このイベントはどこで発生したどういうイベントなのか」という情報を持って、単一の関数(メソッド)を呼び出すだけで良いのではないでしょうか? おそらく、「……というイベントを通知する」という処理ではなく「イベントを通知する」というレベルで、クラス設計するのが妥当だと思います。

souken_200
質問者

お礼

ありがとうございます。 1.どこからコールバックされたか?を元に、 2.次にどんな処理をするのか?(単一の関数(メソッド)を呼び出すだけ)   を次の処理を行ってくれるクラスに通知(メソッドの呼び出し) が適切なのかなと感じました。 .

関連するQ&A

  • C# 子->親の通知にBeginInvokeすると

    親クラスウィンドウのボタンを押すと子クラスを作成して実行し、 子クラスは処理の経過や結果を親クラスに通知する、 というような処理をするために、下のようなコードを書きました。 (主要な部分のみの抜粋です。) 子クラスでは、親クラスへの通知後も引き続いて処理できるよう、 親クラスに対して非同期で通知したいため、 BeginInvoke を使用することにしました。 実行すると、「★A★」で親クラスに通知を実行した際、 ・「★B★」は本来モーダルのはずが裏に回ってしまう ・「★C★」ではクロススレッド呼び出し方法の例外が発生 という問題が生じます。 BeginInvokeするとUIスレッドとは別のスレッドとしてChildEnventReceivedが呼ばれるためと解釈しています。(ほんとかな。) こういったことをしたい場合、どうするのが普通でしょう? 下のコード自体はだいたい合っていて、 コントロールの操作は例えば「★C★」ではbtn.Invoke()するのが普通でしょうか? とすると、そのためのdelegateやメッソドを定義しなければならず、 煩雑になりますね。 C++のPostMessageのようなことがやりたいだけなのですが。 C#は最近取り組み始めたばかりで、勉強中です。 普通はこうする、というような処理をご教授いただければ幸いです。 よろしくお願いします。 ================================================ // 子クラスからの通知イベント delegate void EventHandler(); public Parent {   EventHandler handler;   private void btn_Click(object sender, EventArgs e)   {     btn.Enabled = false;     handler = new EventHandler(ChildEventReceived);     Child child = new Child();     child.SendEvent += hander;     child.Exec();   }   void ChildEnventReceived();     MessageBox.Show("Child State Received");     ★B★このメッセージボックスが裏に隠れてしまう★B★     btn.Enabled = true;     ★C★この操作は「有効でないスレッド間の操作」となる★C★   } } class Child {   public event EventHandler SendEvent;   public void Exec()   {     ★A★ここで親に対して通知する★A★     SendEvent.BeginInvoke(null, null);   } } ================================================

  • [Kinectプログラミング]C++でクラス化

    OpenNI+NITEとOpenCVの環境で、 C++を使ってKinectプログラミングに取り組んでいます。 Visual C++を使っています。 キネクトハッカーズマニュアルという書籍を使っているのですが、 その中のソースコードは全て一つのクラスファイルに記述されているので、 これをクラス化出来ないものかと試行錯誤しています。 http://hagino3000.github.com/kinectbook/ こちらのサイトにソースコードが公開されています。 これの、8_1_detect_gestureというものです。 おおまかな構成は、 コールバック関数の宣言が前半になされていて、 後半にmain関数の処理が書いてある、 といった感じなんですが、 このコールバックに関する記述を、 CallBacks.cppというファイルを作って、 そっちにとりあえず全てコピペしてみました。 そしてCallBacks.hも作成して、 例えばスワイプ検出時のコールバックに関しては、 void XN_CALLBACK_TYPE Swipe (XnFloat fVelocity, XnFloat fAngle, void *pUserCxt); とプロトタイプ宣言を記述しました。 ところが、 main関数内で実際にコールバックを呼び出している部分で、 XnCallbackHandle swipeRightCallback = swipeDetector.RegisterSwipeRight((void*)"Right", Swipe); ともともと書かれていたところを XnCallbackHandle swipeRightCallback = swipeDetector.RegisterSwipeRight((void*)"Right", CallBacks::Swipe); と書き換えただけでは、 型"void(_stdcall CallBacks::*)(XnFloat fVelocity, XnFloat fAngle, void *pUserCxt)"の引数は、 型"XnSwipeDetector::SwipeCB"のパラメーターとの互換性が有りません。 というエラーになります。 そこでSwipeCBについて調べてみると、 http://eris.liralab.it/chris/dox/html/classXnVSwipeDetector.html このページなどに記述がありますが、 SwipeCBの引数は(XnFloat fVelocity, XnFloat fAngle, void *pUserCxt)そのものなのです。 変換がうまく行っていないということだとおもうのですが、 どうすれば良いのでしょうか? かなり限定的な質問になってしまって申し訳ありません。 なにか至らない点ありましたらご指摘ください。

  • 親クラスのポインタ、クラスを指定しないポインタ

    親クラス A (抽象メソッドX、Yの2つを持つ) と 子クラス B-1 (親はA、抽象メソッドX、Y、Zの3つを持つ) 子クラス B-2 (親はA、抽象メソッドX、Y、Wの3つを持つ) のように、子クラスでポリモーフィズムを実現しているとき、 クラスC   「実行時に、iniファイルに(1)と書かれていたら、B-1のクラスで実体化し、   iniファイルに(2)と書かれていたら、B-2のクラスで実体化する」  というクラスを作りたいです。 //////////////////////////////////////////////////////////////// 質問(1) その際、クラスCは、どうやってもZのメソッドや、Wのメソッドは書けない認識です。 (メソッド名もiniファイルから取るようにすれば別でしょうが。) この認識であっていますでしょうか? 質問(2) 逆に、XとYについては、それぞれ挙動の違う処理を行わせることができる認識です。 (クラスCで、親クラスAのポインタ型の変数を用意しておき、  そのポインタに、DLLのインスタンス化したものをいれておけば、  メソッドXとYについては実行可能という認識です)

  • C#で処理中画面を表示したい。

    質問させていただきます。 C#でのボタンなどのイベントで、 仮に一つのボタンのイベントを実行させ、 ボタンを押すと 「処理中」 の別画面を表示し、処理終了後 「処理中」 の別画面は消える という処理を作成したいです。 調べてもわかりませんでしたので困っております。 もしお分かりになられる方がいらっしゃいましたら 是非教えていただければと思います。 よろしくお願い致します。

  • C# スレッドでフォームを扱う

    スレッドとフォームの連携について質問があります。 「開始」ボタンをクリックしたら、 「開始」ボタンのEnableをfalseにして 他のクラスのスレッドで処理を開始します (中断ボタンが押されたら処理をやめるためにスレッド採用) この時、処理が終わったら「開始」ボタンのEnableをtrueに戻したいのです。 デリゲートのコールメソッドを使ったところ、フォームを生成したスレッド以外からフォームををいじってはいけないというエラーがでてしまいました。 [a]ユーザー操作を待ち受けるフォームのスレッド [b]処理系のスレッド このようなスレッドの構成の時、[a]が[b]の処理が終わったことを知り、buttonのプロパティを変更するためには、どうすればよいでしょうか?

  • 「自作クラスの型」にキャストする方法について。

    「自作クラスの型」にキャストする方法について。 Java初心者ですが、よろしくお願いします。 class AAA class BBB ※クラスAAAはクラスBBBのスーパークラス(直属のスーパークラスとは限らない)とします。 class CCC という3つのクラスがあるとして、 この場合、 class CCC{ AAA var; BBB bbb; void test(){ bbb = new BBB(); var = (AAA)bbb; //---★ } } というような、キャストは可能ですよね?(←確認1) 次に(確認1に問題が無い場合)、 クラスAAAとクラスBBBの格納場所(パッケージ関連の話です)について、 AAAとBBBがどういう位置関係にあるときに、上記のキャストは可能になるのでしょうか? AAAとBBBが同一パッケージ内にある時だけでしょうか?(←確認2[質問の核]) で、さらに、 上記の「---★」の所で、 AAAクラスにキャストする処理をしていますが、 この時、AAAクラスのコンストラクタは呼ばれるのでしょうか? (AAAをnewしていないけれど、キャスト処理でnewしたのと同じことになったりしますか?) また、これと同様の質問になりますが、 仮に、クラスAAAの設計が、クラスAAAのインスタンスが生成された場合に、 何らかのコールバック処理が行われるような設計の場合、 この (AAA)bbb というキャストによって、想定しているコールバック処理 は行われたりしますでしょうか?(←確認3) 初心者らしからぬ質問かもしれませんが、 どなたか、どうか分かりやすく教えて下さい。

    • ベストアンサー
    • Java
  • System.Net.HttpWebRequest、もしくはSystem.Net.Sockets を使ったネットワークプログラミングについて(C#)

    一般的なWeb操作(サイトにログインして、そのログインした状態を保持したまま そのサイトを閲覧する)といった内容をプログラム上でやりたいと考えています。 当初、HttpWebRequestクラスを使って組んでみました。 結果は、ログインすることは成功するのですが、2回目に別操作のPOSTを実行しよう とすると、HttpWebRequestインスタンスを再作成せねばならず、ログインした状態が 保持できない状態でのPOSTとなり、うまくいきませんでした。 なので、Socketsクラスを用いて挑戦しているのですが、こちらもうまくいってない状況です。 その状況とは、サイトにログイン(POST)する所がうまくいかないのですが、 コードレベルでいうとSendメソッドを発行した際、Availableプロパティの値が 必ず0になってしまうということです。 この状況までのポイントを記述します。 1.ソケットの接続先ホストのポートは443 2.Connect直後のConnectedはtrue 3.POSTメッセージはHttpWebRequestで成功したメッセージと全く同様  (つまり、メッセージ自体に問題はないはず?!) 4.Send直後のSelectMode.SelectWriteをPoll結果はtrue 5.Send直後のAvailable = 0 個人的に気になるのは、HttpWebRequest、Socketsそれぞれの通信のパケットを キャプチャしてみると、HttpWebRequestの時はSSLによるhandshakeプロトコルのやりとりが 見られるのですが、Socketsの時はhandshakeプロトコルは見られず、POSTメッセージを平文で投げています。 このことからもSocketsクラスでのコーディングに何かの処理が足りない、もしくは どこかが間違っていると思われるのですが、自身では頭打ちといったところです。 回答につきましては、上記問題の解決だけにあらず、冒頭の操作を実行するには こうした方が簡単、分かりやすい。といった意見でもかまいません。 どうぞ、よろしくお願いいたします。

  • JAVAでC/C++の条件コンパイルのようなことはできないでしょうか?

    JAVAでC/C++の条件コンパイルのようなことはできないでしょうか? 実行時に判断するのじゃなくて、 コンパイル時に判断するやり方ないですか? 開発ツール等の環境設定でやるとかじゃなくて・・。 C/C++の条件コンパイルのように、 ソースコーディングすることで、行うやり方。 (たとえば) もし、JDK1.4よりもバージョンがひくければ、 JDK1.3以前でも、存在するクラスを使って メイクする。 その代わりすごいおそーいけどね・・・。 もし、JDK1.4以上であれば とても、パフォーマンスのよいクラスを使った コードをメイクする。 その代わりこれは1.4以上でないと コンパイルできないけどね。 みたいな感じで、 実行時じゃなくて、 コンパイル時にソースコード で条件分岐させてしまうやりかたないですかぁ。 (ないだろうなぁ。) args[0]で起動時の引数で 実行時判断させようとしても、 そもそも、1.4からでてきたクラスとかだと 1.3ではコンパイルすらできない あと、 できれば、したい実現したい機能だけど、 それをするには1.4から登場した クラスを使わなければできないので、 1.3ではあきらめてもらい(そういう仕様にしてもらって) しないようにしようと思ったとする。 そして、 その処理が入ってない1.3版と、 その処理が入ってると1.4版とで、 その差分のせいで、 ソースのバージョンを2種類設ける ということを絶対にやりたくない時とか。 どうするんだろう・・。

    • ベストアンサー
    • Java
  • 【C++】DLLの中身

    親クラス:ParentClassが、 メンバ m_a メソッド GetA SetA それを継承した子クラス:ChildClass が、 メンバ m_a ←オーバーライド m_b ←子クラスで追加 メソッド GetA ←オーバーライド SetA ←オーバーライド GetB ←子クラスで追加 SetB ←子クラスで追加 という構成で、それぞれ別のDLLを作成したとき、 以下のどちらになるでしょうか? 「(1)」の認識であり、必ず、子クラスは、親クラスのファイルサイズよりも大きくなるという認識です。 (1)「ChildClass.DLL」では、 コンパイル時の「ParentClass」の処理内容を内包している。 (※ChildClass.DLLのコンパイル時に、親クラスの処理も、記載されたような状態でDLLが作成される) (2) 「ChildClass.DLL」では、 コンパイル時の「ParentClass」の処理内容を内包せず、 実行時に、親クラスのDLLに委譲している。 また、「(1)」であるならば、 親クラスにバグがあって修正した場合、 必ず子クラスも再コンパイルしなければならない認識ですが合っていますでしょうか? /**************************************/ また、DLLがクラスX、クラスYで構成されているとき、 クラスXのobj と、 クラスYのobj と、 クラスXのlib (クラスYから、クラスXの処理を呼び出せるようにするために、クラスX側からpublic で実行できる関数のIN・OUTの仕様が記載されている) クラスYのlib が、含まれているという認識で良いのでしょうか? .   コンパイル時、libや、objができますが、これらはDLLに内包される

  • スプレッドの制御

    VB6.0について質問です。 スプレッドでマウスのカーソルがあたっている行のバックカラーを変えたいのですがうまくいきません。 MouseMoveイベントでやっています。 以下のソースで実行しており通常だと問題なく実行できるのですが 強制的にマウスカーソルが何行目にあるかを計算していますので スプレッドをスクロールするとスクロールした行だけズレが生じてしまいます。 表示されている行だけを認識する方法はないでしょうか? Private Sub spdlist_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single) Dim actrow With spdlist .Col = -1 actrow = Int(y / 400) .Row = actrow .BackColor = vbred End With End Sub

専門家に質問してみよう