- 締切済み
基本的な認識不足(クラス設計)?
現在、ポリモーフィズムを使って、電卓プログラムを作っているんですが、コンパイルは通るんですが、アクションをおこしたら、フリーズしてしまいます。 ソースをのせますので、どなたか、ご指摘お願いします。開発環境はC++でWin32Apiです。 [抽象関数] class Virtual{ public: Virtual(){} virtual ~Virtual(){} virtual char RetOp() = 0; }; [継承したクラス] class Number : public Virtual{ char ch; public: Number(char s){ ch = s; } virtual ~Number(){} virtual char RetOp(){ return ch;} }; [WndProc内] static string str; Virtual *PoliM = NULL; switch(Message){ case WM_COMMAND: switch(LOWORD(wParam)){ /*ボタン7が押されたら。*/ case ID_Bt: PoliM = new Number('7'); break; } /*string型に7を足す。*/ str += PoliM->RetOp(); /*hEditは表示先*/ SetWindowText( hEdit, str.c_str()); delete PoliM; } よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- terra5
- ベストアンサー率34% (574/1662)
WndProcでは、MessageがWM_COMMANDでないい場合も、wParamがID_Btで無い場合もありますから、 その場合にこのままだとPoliMがNULLのまま str += PoliM->RetOp(); を実行しようとします。 だから、#3の方の回答のような修正が必要になります。 ただし、PoliMはローカルの自動変数でNULLで初期化されるため、この場合は最後のNULL代入は不要です。 > switchの外で実行したいんですが、(じゃないと、ポリモーフィズムの意味が、、、) 中でもポリモーフィズムの意味はあると思います。 というか、これが中か外かは関係無いのでは? この場合はVirtual,Numberというクラスがポイントでしょう。
- 405
- ベストアンサー率50% (17/34)
問題はやはり、PoliM==NULLの状態でPoliMへのアクセスが発生している所だと思われます。 なので、単純に問題の部分で実体が有る/無しの判定を行えば良いんじゃないかと… 例) if( PoliM != NULL ) { /*string型に7を足す。*/ str += PoliM->RetOp(); /*hEditは表示先*/ SetWindowText( hEdit, str.c_str()); delete PoliM; PoliM=NULL; } 注) 最後のPoliM=NULL;をお忘れ無く。 ただ、私はポリモーフィズムについての知識がありませんので、ご希望の動作になるかどうかは分かりません。
お礼
ありがとうございます。 例のようにすると、正常に動きました。 ありがとうございました。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 一体どこに問題があるのでしょうか? #1 で指摘の通り、PoliM == 0 にもかかわらず、RetOp()を呼んではいませんか?
お礼
回答ありがとうございます。 何個か別の方法を試した結果、やはり PoliM = NULL の状態でのアクセスに問題があったようです。 ありがとうございました。
- 405
- ベストアンサー率50% (17/34)
抜粋されたソースなので、ちょっと読み切れませんが、 PoliMが実態を持たないまま str += PoliM->RetOp(); や delete PoliM; を実行している可能性はどうでしょうか? PoliM==NULLの状態で上記の動作を実行しようとして、飛んじゃってる気がします。
お礼
早速の回答ありがとうございます。 Virtual *PoliM = NULL; として、 case ID_Bt: PoliM = new Number('7'); break; で、実体化して str += PoliM->RetOp(); この一連の操作は、参考書のポリモーフィズムのサンプルプログラムのままなのですが、 ただ、いろいろ試すと、 case ID_bt: PoliM = new Number('7'); str += PoliM->RetOp(); SetWindowText( hEdit, str.c_str()); break; と、このように、記述すると、期待どおりのアクションをします。 私としては、case ID_bt:の中は new Number('数字'); だけにして、 str += PoliM->RetOp(); SetWindowText( hEdit, str.c_str()); は、switchの外で実行したいんですが、(じゃないと、ポリモーフィズムの意味が、、、)一体どこに問題があるのでしょうか?
お礼
回答ありがとうございます。 参考書に厳密に、 default: return; を足すと、正常に動きました。 switch(LOWORD(wParam)){ case ID_bt: PoliM = new Number('7'); break; default: return; } str += PoliM->RetOp(); SetWindowText( hEdit, str.c_str()); delete PoliM; ご指摘どおり、MessageやwParamの状態で、PoliMがNULLのまま,PoliM->RetOp();を実行しているようす。 ただ、caseで用意した条件以外にdefaultが必要な理由が良く分かりません。