Aクラスの値をBクラスのメソッドで使いたい場合オブジェクト指向でどのように記述すればいいのでしょうか?
具体的に言いますと
win32apiにてウィンドウクラスとボタンクラスを作成しました。
ですがボタンクラスでボタンを作るためにはCreateWindow(...)でウィンドウクラスのハンドルを渡さなければいけません。
この場合どうするのが正解なのでしょうか?
publicで値を渡す、メソッドで渡す、ウィンドウクラス内でボタンクラスを使うなどいろいろ考えられますがどのようにすればいいのでしょうか?
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
(残念な方向の)個人的な経験からの意見ですが…
ウィンドウクラス
の中にウィンドウハンドルを完全に閉じ込める(そのクラスの外側ではハンドルの値を参照できない)実装を考えているのだとしたら,
その方針自体を 諦めた方が 楽になります.
- Win32APIでウィンドウに関する何かをしたい場合には,ウィンドウハンドルが必要.
→「ウィンドウクラス」がハンドル値を独占的に抱えるのだとしたら,
外部からウィンドウに対して行いたい操作に対応するAPI全てに相当するメソッドを公開するような実装になる.
(単にAPIの引数を1個減らしただけのメソッドが大量に……)
あるAPIに対応するメソッドがこのウィンドウクラスに無い場合,
API関数を使っていればさくっと達成できた事柄が「このクラスを使うせいでできない」とかいう謎の縛りプレイみたくなる.
- 「ウィンドウクラス」がウィンドウハンドル値のgetterみたいなのを公開してしまうとしたら,もはやウィンドウクラスはウィンドウをまともには管理できなくなる.
だって,クラスの外部ではウィンドウに何でもできる(ウィンドウを閉じることだってできる)のだから……
「ウィンドウクラス」とは何だったのか?
- ウィンドウハンドル値のgetterをprotectedにして,このクラスの実装では足りない機能がある場合は,派生クラスで何とかしてね! という方向も考えられるが…
派生クラスのコードが,ウィンドウクラスから見れば「外部」であることには変わらないので,まぁ,うん……
投稿2020/06/27 02:10
編集2020/06/27 02:12総合スコア11996
0
ベストアンサー
Visual Studio (Codeではない方)でC++、Win32 APIを使ったデスクトップウィンドウアプリケーションの開発では、20年以上前からMFC(Microsoft Foundation Class)と言うC++クラスライブラリが利用できるようになっています。多くのウィンドウシステムでもそうだと思いますが、ボタン(Win32で言う"BUTTTON"
クラスのコントロール)やテキストボックス(Win32で言う"EDIT"
コントロール)などは、ベースとなるウィンドウを拡張したシステムに登録済みのウィンドウです。そのようなものはWindowsでは「コントロール(Control)」と呼びますが、他のOS、プラットフォームではウィジェット(Widget)などと呼ばれることがあるのはご存じのことと思います。MFCの話に戻ると、ウィンドウやボタンなどの各コントロールを表すにあたって、C++のクラスとしておおむね以下のようなかたちになっています。(実際はC++のテンプレートであったり、マクロを多用していたり、かなり複雑です)
C++
1// ※完成したコードではありません。例の為の疑似コードとしてみてください。 2 3// 基本のウィンドウ 4class CWnd { 5public: 6// 基本のウィンドウとして持っているべきウィンドウハンドルとかウィンドウスタイルとか座標情報とかのメンバー変数群 7// 基本のウィンドウとして持っているべきイベントハンドラ(コールバックなどを用いたメンバー関数群) 8 virtual void OnCreateWindow() {}; // WM_CREATEでコールバックされるようなメンバー関数 9}; 10 11// ボタン 12class CButton : public CWnd { 13// BUTTONコントロールとして動くための特有のメンバー変数やメンバー関数。 14// メンバー関数は必要に応じてベースクラスのものをオーバーライド。 15}; 16 17// テキストボックス 18class CEdit : public CWnd { 19public: 20// テキストボックス("EDIT"コントロール")として動くための特有のメンバー変数やメンバー関数。 21// メンバー関数は必要に応じてベースクラスのものをオーバーライド。 22 virtaul void OnCreateWindow() { 23 CWnd::OnCreateWindow(); 24 // TODO: テキストボックス特有の処理を追加 25 } 26};
ダイアログボックスのようにウィンドウが子コントロールを持つ場合、例えば以下のようなクラス構造になるでしょうか。
C++
1// ※完成したコードではありません。例の為の疑似コードとしてみてください。 2 3class CUserDialog : public CWnd { 4public: 5 CEdit editValue; // 値入力 6 CButton buttonOK; // [OK]ボタン 7 CButton buttonCancel; // [キャンセル]ボタン 8 void OnClickOK() {} // OKボタン押下時のイベントハンドラを表すメンバー関数 9}; 10// ※実際にはMFCにはCDialogと言うダイアログボックスを表す定義済みのクラスがあります。
MFCや他のプラットフォームのウィンドウクラスライブラリについてネーミングルールなどの差はあるでしょうが、おおむね同じような構造になっているはずです。つまり、そのクラスオブジェクトの関係性を示す上でそれぞれ適切と考えられる値や受け渡し制御のやり方があるのです。と言っても方法について常に唯一無二の「正解」がある訳ではなく、独自のクラスを作るのであればまずは動かすことを優先に、使いたいように使えば良いとも思います。C++/Win32APIでは前述のMFCのほかに、WTL(Windows Template Library)と言うものがあります。クロスプラットフォームではQtが有名です。質問者さんの場合はWin32APIをもとに、オブジェクト指向を意識しつつ(恐らく)勉強を目的として本質問を挙げられたのだと思いますが、こういった既存のフレームワークのソースを覗いてみると分かってくるものがあるはずだと思いますので、読んでみるのもお勧めです。
投稿2020/06/27 01:08
編集2020/06/27 23:53総合スコア9256
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/27 08:10
2020/06/28 00:08
2020/06/29 06:55
0
「お好きに」としか答えようがないかな。
C++
1 Window win; 2 Button btn = win.createButton(); // Windowに作ってもらう
とか
C++
1 Window win; 2 Button btn(win); // 作るときにWindowを渡す
とか
C++
1 Factory fac; 2 Window win = fac.createWindow(); // 作成はすべて 3 Button btn = fac.createButton(); // Factoryが行う
とか。
投稿2020/06/26 22:36
総合スコア16612
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/27 03:18