• 締切済み

基本的な認識不足(クラス設計)?

 現在、ポリモーフィズムを使って、電卓プログラムを作っているんですが、コンパイルは通るんですが、アクションをおこしたら、フリーズしてしまいます。 ソースをのせますので、どなたか、ご指摘お願いします。開発環境は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; } よろしくお願いします。

みんなの回答

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.4

WndProcでは、MessageがWM_COMMANDでないい場合も、wParamがID_Btで無い場合もありますから、 その場合にこのままだとPoliMがNULLのまま str += PoliM->RetOp(); を実行しようとします。 だから、#3の方の回答のような修正が必要になります。 ただし、PoliMはローカルの自動変数でNULLで初期化されるため、この場合は最後のNULL代入は不要です。 > switchの外で実行したいんですが、(じゃないと、ポリモーフィズムの意味が、、、) 中でもポリモーフィズムの意味はあると思います。 というか、これが中か外かは関係無いのでは? この場合はVirtual,Numberというクラスがポイントでしょう。

ootutu
質問者

お礼

回答ありがとうございます。 参考書に厳密に、  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が必要な理由が良く分かりません。

  • 405
  • ベストアンサー率50% (17/34)
回答No.3

問題はやはり、PoliM==NULLの状態でPoliMへのアクセスが発生している所だと思われます。 なので、単純に問題の部分で実体が有る/無しの判定を行えば良いんじゃないかと… 例) if( PoliM != NULL ) { /*string型に7を足す。*/ str += PoliM->RetOp(); /*hEditは表示先*/ SetWindowText( hEdit, str.c_str()); delete PoliM; PoliM=NULL; } 注) 最後のPoliM=NULL;をお忘れ無く。 ただ、私はポリモーフィズムについての知識がありませんので、ご希望の動作になるかどうかは分かりません。

ootutu
質問者

お礼

ありがとうございます。 例のようにすると、正常に動きました。 ありがとうございました。

回答No.2

> 一体どこに問題があるのでしょうか? #1 で指摘の通り、PoliM == 0 にもかかわらず、RetOp()を呼んではいませんか?

ootutu
質問者

お礼

回答ありがとうございます。 何個か別の方法を試した結果、やはり PoliM = NULL の状態でのアクセスに問題があったようです。 ありがとうございました。

  • 405
  • ベストアンサー率50% (17/34)
回答No.1

抜粋されたソースなので、ちょっと読み切れませんが、 PoliMが実態を持たないまま str += PoliM->RetOp(); や delete PoliM; を実行している可能性はどうでしょうか? PoliM==NULLの状態で上記の動作を実行しようとして、飛んじゃってる気がします。

ootutu
質問者

お礼

 早速の回答ありがとうございます。 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の外で実行したいんですが、(じゃないと、ポリモーフィズムの意味が、、、)一体どこに問題があるのでしょうか?

関連するQ&A