- ベストアンサー
オーバーライドとオーバーロードについて
- CTestDlgクラスのCreate関数のオーバーライドとオーバーロードについて説明してください。
- Create関数に引数が異なる場合、オーバーライドとは言わずにオーバーロードと呼ぶことができます。
- また、引数が異なる関数同士は使用することができず、エラーが出ます。それについても教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>以上のような場合において、 > >1.Create(CWnd *pWnd)は、引数が異なるため >virtual BOOL Create( >LPCTSTR lpszTemplateName, >CWnd* pParentWnd = NULL >); > >をオーバーライドしたとは言わず、オーバーロードしたということで良いのでしょうか? そうです。 >2.オーバーロードしたということであれば、 >Create(CWnd *pWnd)と >virtual BOOL Create( >LPCTSTR lpszTemplateName, >CWnd* pParentWnd = NULL >); >の両方の関数が使えると思っていたのですが、後者方は引数が異なるとエラーが出て使えませんでした。 > >どうしてなのでしょうか? 型が類似しているためにどの関数を呼び出しているのかが、コンパイラに判断できないということです。 この場合は明示的に呼び出す必要があります。 例えば、pWndを親ウィンドウへのポインタとすると、 CTestDlg::Create(CWnd *pWnd) を呼び出す場合は、 CTestDlg* pDlg = new CTestDlg(); pDlg->Create(pWnd); virtual BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL ); を呼び出す場合は、 CTestDlg* pDlg = new CTestDlg(); ((CDialog*)pDlg)->Create(MAKEINTRESOURCE(CDlgtestDlg::IDD), pWnd); か ((CDialog*)pDlg)->Create(MAKEINTRESOURCE(CDlgtestDlg::IDD)); となります。
その他の回答 (3)
- darksky
- ベストアンサー率66% (38/57)
余計なお世話ですが、最後に1つだけコメントします。 pParent->EndTestDlg(); delete this; 上記のpParentは、オーバーロードしたCreateでセットされているはずです。 そのため、if文をコメントすると、pParentが正しく設定されていので、エラーがでるのではないでしょうか。
お礼
本当に心から感謝いたします。 いつも、何度もありがとうございます。 void CModelessDlg::EndTestDlg() { m_pTest = NULL; } は、無視してもエラーが出ないと考えたのですが。。。
補足
言われている意味がわかりました。 pParent->EndTestDlg(); を実行しようとして、実行出来ないのでエラーが出ていました。
- darksky
- ベストアンサー率66% (38/57)
別の質問でのソースですが、 void CTestDlg::PostNcDestroy() { // TODO: この位置に固有の処理・・・ if( pParent != NULL) { pParent->EndTestDlg(); delete this; } オーバーロードしていないCDialog::Createでは、 pParent がNULLのままではないですか。 ということは、if文の処理が処理されない訳ですね。 ここが重要なのではないでしょうか。
お礼
回答ありがとうございます。 確かに仰せの通りです。 オーバーロードしたほうは、そのコンストラクタも実施されているし。。。 if文をコメントアウトして、if文の中を強制的に実行してみましたが、やはりエラーが出ました。 あとは自分で考えてみます。
- darksky
- ベストアンサー率66% (38/57)
>(CDialog*)m_pTest->Create(MAKEINTRESOURCE(CTestDlg::IDD), this); これではエラーになります。試された方法でもいいですが、 ((CDialog*)m_pTest)->Create(MAKEINTRESOURCE(CTestDlg::IDD), this); ならOKです。 あと、Createの方法と一度閉じた後に再度Createできないことは全然関係ありません。 ちゃんと後処理を行っているかの問題です。
お礼
回答ありがとうございます。 ((CDialog*)m_pTest)->・・・でもうまくいくことが確認できました。 >あと、Createの方法と一度閉じた後に再度Createできないことは全然関係ありません。 あっ すいません。また言葉足らずだったようで、当然、関係無いことは承知しています。 但し、今回の場合は、オーバーロードした関数にてCreateすることと、継承元にてCreateすることは、結局同じ引数にてCreateしている(?)と思えるのですが。。。。 結果的にエラーが出るということは、違う処理をしているということになりますが、なにが異なっているのか分かりません。
お礼
回答ありがとうございます。 自分でも本でオーバーロードとオーバーライドを勉強しましたので、これらの相違と今回関数が呼び出せない理由はわかりました。 実際に教えていただいた方法でトライしたところ、 (CDialog*)m_pTest->Create(MAKEINTRESOURCE(CTestDlg::IDD), this); では、関数が不正な 2 個の実引数をともなって呼び出されました。のエラーが出ましたので、以下のように変更しました。 m_pTest->CDialog::Create(MAKEINTRESOURCE(CTestDlg::IDD), this); この場合は、モードレスダイアログが表示されましたが、一度閉じると2度目は表示されないエラーが出ました。