質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

2128閲覧

C++ オブジェクト指向 クラス間の値

ganjo

総合スコア9

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/06/26 19:42

Aクラスの値をBクラスのメソッドで使いたい場合オブジェクト指向でどのように記述すればいいのでしょうか?

具体的に言いますと
win32apiにてウィンドウクラスとボタンクラスを作成しました。
ですがボタンクラスでボタンを作るためにはCreateWindow(...)でウィンドウクラスのハンドルを渡さなければいけません。
この場合どうするのが正解なのでしょうか?
publicで値を渡す、メソッドで渡す、ウィンドウクラス内でボタンクラスを使うなどいろいろ考えられますがどのようにすればいいのでしょうか?
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

(残念な方向の)個人的な経験からの意見ですが…

ウィンドウクラス

の中にウィンドウハンドルを完全に閉じ込める(そのクラスの外側ではハンドルの値を参照できない)実装を考えているのだとしたら,
その方針自体を 諦めた方が 楽になります.

  • Win32APIでウィンドウに関する何かをしたい場合には,ウィンドウハンドルが必要.
    →「ウィンドウクラス」がハンドル値を独占的に抱えるのだとしたら,

 外部からウィンドウに対して行いたい操作に対応するAPI全てに相当するメソッドを公開するような実装になる.
(単にAPIの引数を1個減らしただけのメソッドが大量に……)
あるAPIに対応するメソッドがこのウィンドウクラスに無い場合,
API関数を使っていればさくっと達成できた事柄が「このクラスを使うせいでできない」とかいう謎の縛りプレイみたくなる.

  • 「ウィンドウクラス」がウィンドウハンドル値のgetterみたいなのを公開してしまうとしたら,もはやウィンドウクラスはウィンドウをまともには管理できなくなる.

だって,クラスの外部ではウィンドウに何でもできる(ウィンドウを閉じることだってできる)のだから……
「ウィンドウクラス」とは何だったのか?

  • ウィンドウハンドル値のgetterをprotectedにして,このクラスの実装では足りない機能がある場合は,派生クラスで何とかしてね! という方向も考えられるが…

派生クラスのコードが,ウィンドウクラスから見れば「外部」であることには変わらないので,まぁ,うん……

投稿2020/06/27 02:10

編集2020/06/27 02:12
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2020/06/27 03:18

実際C#などで一般的に使うWPFとかでも普通にWindowハンドル取れますもんね。取れないといろいろ困るし。
guest

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
dodox86

総合スコア9256

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/06/27 01:13

C言語での生Win32APIを使った簡単なウィンドウアプリケーションのソースと、それに相当するMFCのソースを見比べてみると、Win32APIのRegisterClass APIを用いた「ウィンドウクラスの登録」、CreateWindowによる登録済みウインドウクラスのインスタンス化の対比が分かってくると思います。各クラス間の値の受け渡しは、メンバー変数や各種のアクセッサー関数と対比してみると良いです。
ganjo

2020/06/27 08:10

いずれはプロになりたいと思いオブジェクト指向を勉強のため、意識して書いていこうと思い質問させていただきました。 win32apiの中身がどうなっているのか等、自分でもいろいろ試したり、ソースコードを見て今後も精進していこうと思います。 それにオブジェクト指向に気を取られすぎて、作りたいものも作れなければ意味がないですし、何のためにそうするのかよく考えて書いていこうと思います。(当たり前ですが...何でもかんでもクラス化、と見失っていたかもしれません。) 皆様の回答とても参考になりました。 回答をしていただいた皆様ありがとうございました。
dodox86

2020/06/28 00:08

回答中に補足で書くつもりだったのですが、抜けていたので追加でコメントさせていただきます。Win32とC言語でウィンドウアプリを作るのに対比して古くからのC++フレームワークであるMFCなどを挙げましたが、最近はWindowsにおいてC++/MFCでのアプリ作成はどちらかと言うと(否、かなり?)レガシーな扱いになっています。様々な理由で推奨はC# + .NET系、です。それでもウィンドウシステムのAPIをネイティブでC言語/C++で扱え、まぁまぁ手軽に扱えるものとしてWin32を対象にするのはお勧めとはいかないまでも、悪いとは言えないと個人的には思います。勉強目的もあるのであれば、貴重な時間を溶かさずハマらない程度に向き合ってみるのが良いと思います。
ganjo

2020/06/29 06:55

わかりました。 はまらない程度に頑張ってみます。 ありがとうございます。
guest

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

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問