- ベストアンサー
VisualC++ドキュメント/ビューアキテクチャについて
ものの本には『データはドキュメントクラスで管理し、ビュークラスではそこからデータをもらってくる』とし、データをドキュメントクラスのメンバ変数で作ることを推奨しているのですが、 データをファイルから読み込み、ビュークラスで表示、加工するようなアプリケーションにおいて、 (a) データをドキュメントクラスのメンバ変数(public)で作る、 (b) データを外部変数で作りどこからでも参照変更できるようにする、 でどう違うのでしょうか。 c/c++初心者です。よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
どうしても言語から入ってしまうと言語仕様として どちらも出来てしまうので迷いますよね。 違いというと。。。 そのメンバ変数なり外部変数をアプリケーション上で 参照出来る期間(変数実体の寿命?)を考えてみます。 (a)の場合まずドキュメントオブジェクトのインスタンスが存在する間。 (b)はアプリケーション起動~終了迄。 となります。 変数をpublicなり外部変数なりにした場合の弊害について はsssoheiさんがおっしゃっている通りです。 オブジェクトを使ってアプリケーションを実装する考え方 (オブジェクト指向ですね)を身につけてください。 そちら側から考えてみるとわかりやすいですよ。 所詮言語は実装を表現する手段にすぎないのですから。。。
その他の回答 (4)
- sssohei
- ベストアンサー率33% (33/98)
> > 内蔵をみせながら歩くようなもの > みせるけどいじられることはない、ということですか? 説明が不適切でした^^;ごめんなさい。 publicな変数は外からいじることが出来るので、どちらの場合もいじれますね^^; なお、(すこし正確ではありませんが)関数(インターフェース)を通じてメンバ変数にアクセスする様にする事を「カプセル化」と言います。 「中身を気にしなくても良くなる」というのが効用です。 # 作者を信頼すれば、、ですが。 例えば、ラジカセを操作するのに、CDを入れて、再生ボタンを押す。という事だけ知っておけばいい。ですよね。このとき。「CDを入れる」、「再生ボタンを押す」と言うのがインターフェースを通じた処理な訳です。 「ラジカセ」は「クラス」 「CDを入れる、再生ボタンを押す」はメンバ関数に相当します。 メーカーを信頼すれば、ラジカセがどのように動作しているかを気にする必要はありません。 CDの状態によってレーザーの強さを調節したりするのはラジカセに任せてしまいます。 外から、人がいじれると、下手したら壊れてしまうかも知れません。 # 分かってる人(制作者)にとっては、いじれた方が良いのかも知れませんが、全体から見れば、いじれない方が良いわけです。 他の部分も同様です。 そのため、パッケージで包んで、さわれなくしてある。と言うわけです。 こうすれば、外部からの介入の可能性を絞れますので、内部に処理を書きやすくなる、と言うわけです。 説明がうまく出来ず、長文になってしまいました(本当に、ごめんなさい。 馴れると感覚的に良さが分かってくると思います。
お礼
オブジェクト指向は概念的にはわかっているつもりなんですが、いざコードを書く段になると、どこからでも何でもいじりたくなってしまいます。 いろいろな例題でもっと慣れる必要があると思います。 親切な説明を頂き、感謝しております。
- wr250zb
- ベストアンサー率41% (7/17)
>CxxDoc* pDoc = GetDocument(); これはビューにと結びついているドキュメントオブジェクトのポインタを取得しています。 ドキュメント、ビューのオブジェクトインスタンスを生成 しているのはMFCの内部が行っています。 このあたりについてはここで書くにはたいへんなので、 MSDNヘルプの「ドキュメント、ビューアーキテクチャ」 のあたりを見てください。 またはCXXXDocのコンストラクタにブレークポイント 張って止まったら、「コールスタック(Alt+7キー)」 でどこから呼ばれているか見てみるのも良いかもしれません。
お礼
MFCでプログラムを書くのは、私の場合、お釈迦様の手のひらでおサルさんが遊ぶようなものみたいですね。 もう少し勉強してみようと思います。 いろいろ丁寧に説明いただき、ありがとうございました。
- sssohei
- ベストアンサー率33% (33/98)
> publicメンバ変数と、外部変数(正式名称かどうかわかりませんが、関数の外で定義する変数) グローバル変数で良いと思います>呼び方 それはさておき、グローバル変数は使わない、というのが現在の主流です。>メリットよりもデメリットが大きいので どうしても使いたいというような場面が思い当たらないのですが、いかがでしょうか?^^; なるべく、作る人間が楽になるような方法をとっていかないと、なかなか大変だと思います。 C++はCの流れを踏んだ言語なので、残っている遺物的な(というと言い過ぎかも知れませんが)言語仕様も残っています。 ちょっと極端な例えですが、 「データをドキュメントクラスのメンバ変数(public)で作る」というのは、内蔵をみせながら歩くようなものです。 「データを外部変数で作りどこからでも参照変更できるようにする」というのは、目の前に誰もいなくても、いつの間にか財布の中身がかわってしまったり、体の中をいじられてしまったり、、を出来るようにするようなものです。
補足
わかりやすい説明ありがとうございます。 > 内蔵をみせながら歩くようなもの みせるけどいじられることはない、ということですか?
- sssohei
- ベストアンサー率33% (33/98)
大抵、データをドキュメントクラスのprivateメンバ変数にしておいて、publicなメンバ関数で間接的に操作します。>カプセル化 はじめは面倒なように感じるかも知れませんが、悪質なバグが減ることが多く、非常に効率の上がることが多いです。 この様にすることで思わぬ書き換えを防ぐコードを入れたり、と色々管理がしやすくなります。 関連している物がまとまっている方がわかりやすいと思うのですが、いかがでしょうか? また、データはそれぞれのクラスに密接に結びつくので、必要な所に、必要なだけ利用出来るというわけです。 ドキュメント/ビューアキテクチャに限らず、C++全般に対して重要な考え方だと思います。
補足
privateメンバ変数+publicメンバ関数が有効だということは何となく理解できました。 publicメンバ変数と、外部変数(正式名称かどうかわかりませんが、関数の外で定義する変数)はどのように使い分けるのでしょうか。
補足
ありがとうございます。変数の違いについては理解できた(つもり)と思います。 で、MFC AppWizardが生成したコードをさらっと眺めてみたのですが、CxxDocの宣言らしきものが見当たりません。CxxDocのオブジェクトはどこで作られ、いつ消えるのでしょうか。 CxxView::OnDraw(CDC* pDC)の中で、 CxxDoc* pDoc = GetDocument(); がありますが、ここですか? 的をはずれは質問のような気がしますが、初心者に免じ、よろしくお願い致します。