- ベストアンサー
C++の関数の継承を判定する方法
- 個々の関数について継承しているかどうかを判定する方法を探しています。
- C++のクラスCBaseを規定クラスとして、クラスCTestがCBaseを継承しています。
- 現在は例外を使用して判定する方法を考えていますが、他に効果的な方法はありませんか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
結局、基底クラスから派生クラスが呼ばれるのは、 内部的にはバーチャルテーブルを利用した関数ポインタで 切り分けて呼んでいるわけで。 例外を使って、呼び元がそれを検出したとして、それが どの派生クラスの例外なのかわからなければ、処理のしようもない。 しかし、呼び元が、派生クラスのタイプを意識するような 仕組みになったら、そんなクラス設計は破綻してますからねぇ。 ウィンドウメッセージの処理だということなら、 こんな感じになるんじゃないのかなと。 http://www.kab-studio.biz/Programing/Codian/MxA/07.html 基底クラスはデフォルトのメッセージ処理関数を呼ぶだけ。 派生クラスは自分の処理すべきメッセージなら処理して、そうでなければ 基底クラスのデフォルトメッセージ処理関数を呼ぶ。 >未定義を一挙に親で処理したかった 親は普通あんまり仕事をしないもんですよ。 クラス間の結びつきが強くなるほど、メンテナンス性が失われるので。
その他の回答 (3)
- machongola
- ベストアンサー率60% (434/720)
こんばんは。 C++のクラスを使用してウィンドウをラップした時、ウィンドウプロシージャとオーバーライドの折り合いをどの様にするのかは、色々な手段があります。 case WM_SYSCOMMAND: (this->*m_pmf_wm_syscommand)(wParam, lParam); 例えば、MFCでは上記の様にメンバ関数ポインタを使用しています(実際のMFCではもっと複雑であり、名前も違います)。 初期状態では「m_pmf_wm_syscommand」に、基本クラスのメンバ関数が設定されています。 IDEでメッセージに対応したメッセージハンドラを追加するとメンバ関数がオーバーライドされ、「m_pmf_wm_syscommand」にはオーバーライドされたメンバ関数が設定されます。
お礼
ご回答ありがとうございます。 メンバ関数ポインタを使用したことが無かったんですが、基底の判別が==NULLでできるのとtemplateを使用するのが簡単そうですね。 オーバーライドする時どう設定するのか調べてみます。
- hidebun
- ベストアンサー率50% (92/181)
誰がどのように働くか、というのを抽象化して、 柔軟性を持たせるのが継承の役割だったりするしなぁ。 それがわかっていないというのは、設計が崩壊してるって ことじゃないのかなぁ。 ちなみに私なら、Doxygenでクラス図を吐かせて、確認しますけど。 コードを修正していらぬバグを埋め込みたくないし。
お礼
ご回答ありがとうございます。 もともとは未定義のvirtual関数が詰まった内部クラスを基底として作成したクラスを、親(内部クラスの)から呼び出す際に未定義を一挙に親で処理したかったんですが、一般化された方法がわかりませんでした。 クラス図生成してみます。
- Yune-Kichi
- ベストアンサー率74% (465/626)
まず,汎用的な方法はおそらく存在しません。 # ときたま,汎用的な方法が思いも付かないような方法で存在するのがC++の恐いところなので,断定はしません。 ・目的は何ですか たとえば,目的が派生クラスに実装を強制するのであれば,純粋仮想関数にすればよいです。 目的によっては,別の方法で対処できるかもしれませんし。 ・処理系は何ですか 場合によっては,処理系が方法を提供してくれているかもしれません。
お礼
ご回答ありがとうございます。 環境はVC++2008で、ウィンドウのクラスを作成したので、WndProcの扱いに困ってました。 MFCの呼び出し方法(AfxWndProc<-AfxCallWndProc)が参考になりそうです。
お礼
ご回答ありがとうございます。 メンバ関数ポインタを使用したことが無かったんですが、基底の判別が==NULLでできるのとtemplateを使用するのが簡単そうですね。 オーバーライドする時どう設定するのか調べてみます。
補足
すみません。前の方と間違えました。 返信ありがとうございます。 内部的に結構ポインタを保持しておかないとクラス単位の関数管理とかはできないんですね。 基底クラスは確かに派生クラスに対応する処理をするべきではないと思います。 >>基底クラスはデフォルトの メンバ関数ポインタでそれを書くか、WndProcの状態を保存しておいて子クラスからデフォルトを呼び出すとかでも全然いいと思いました。