8

初心者プログラマーとして、OOPの基本を学んだばかりですが、練習プログラムの基本的な包含構造に関して多くの問題に遭遇しました。私はさまざまな書面およびオンラインのリソースを使用してプログラミングを自分自身に教えてきました。しかし、ここに私の問題があります(まあ、そのうちの1つ...):

抽象化、カプセル化、クラス間の結合度の低さの重要性を理解している一方で、プログラムの構造化とクラスの設計に非常に苦労しています。お互いを知るための異なるファイルのクラス

もちろん、これは私の大きな問題であり、すべての基本的なプリンシパルOOPをウィンドウから外し、コードにグローバル変数、すべての前方宣言を入力し始めた後、私が望む方法でのみ機能する、ずさんなハックっぽいコードになりました。どこでも、そしてクラスのメンバーを公開します。

簡単に言えば、私のプログラミングは混乱しています... C ++は私の最初のプログラミング言語であり、オブジェクト指向の方法で設計/作成するために最善を尽くしても、ファイルの醜い混乱に終わります。すべてのファイル、およびめったに機能しない手続き型とOOPスパゲッティコードの奇妙な組み合わせ!

私は自称プログラミング初心者であり、プログラムの構成方法を学ぶのに時間がかかることを認めますが、もうすぐ終わりです。私の問題は、OOPについて少し知っているという事実に起因していることを私は知っています。単一のタスクを処理する独立したクラスを作成したいことはわかっています。しかし同時に、プログラムの他の部分の存在を各クラスに適切に警告する方法がわかりません。どんな食べ物を食べるべきかはわかっているが、フォークの使い方はわからないようなものです...

それが私の問題です。そして、私が持っているいくつかのより具体的な質問をさらにフォローアップするために:

  • C ++マルチファイルプロジェクトでは、main()関数を独自のクラス内に配置するのが普通/必要ですか?それとも、main()をグローバルスコープに残すのが標準的なことですか?

  • 以前、私がC ++で作成した手続き型プログラムでは、main.cppファイルの先頭に定数変数または#definesがグローバルスコープにあることは珍しくありませんでした。たとえば、画面の寸法やその他の有用な情報は、プログラムの開始時に定義される可能性があります。OOPでは何が起こりますか?この慣行は完全に避けるべきですか?または、MAIN.Hファイルを作成し、プロジェクト内の他のすべてのヘッダーに#includeしますか?私はこれについて何をすべきか分かりません...

  • 私の最初の中規模の練習用OOPプログラムを書いているとき、StateMachineクラスを書き始めたとき、私の仕事はひどく止まりました。StateMachineクラスに、プログラムが使用する可能性のあるすべての画面状態を含めることが私の意図でした。ただし、StateMachineクラスが他のStateクラスの一部を認識していないように見えるという問題が発生しましたが、それらはすべて#includeされていました。人々がクラスの前方宣言を行うのを見たことがありますが、それは必要ですか?私はあちこちでクラスの前方宣言をスパムするべきですか、それともコードの臭いですか?

  • 最後に、#includeコマンドと前方宣言コマンドの順序は重要ですか?

これはおそらく非常に基本的な質問だと思いますが、単一ファイルの手続き型c++初心者プログラムから複数ファイルのOOPプログラミングへの移行に非常に苦労しています。すべてが正しく機能するようにプログラムを構成するための一般的な経験則はありますか?私はインクルードガードを使用していますが、すべてのソースファイルのすべてのヘッダーを#includeできない理由はありますか?各クラスの各ヘッダーファイルに#includeされたcommon.hファイルが必要ですか?

コミュニティが私に与えることができるどんな助け/アドバイスにも本当に感謝します。これは、OOPスキルの開発を開始する前に通過する、単純でありながら重要なハードルであることを私は知っています。私は、クラスを互いに分離しておくことの重要性を頭の中で掘り下げようとしてきました。クラス/ファイルを実際に相互作用できるように設定する方法がわからないほどです。助けてくれてありがとう!

4

3 に答える 3

4

OOPは、クラスを使用した通常の関数型プログラミングのようには考えられません。これは間違ったアプローチであり、誤解を招く可能性があります。

アプリケーションのアーキテクチャを設計することは非常に重要であり、それについて書かれた本があります。アプリの構造を適切に設計すればするほど、コーディングが容易になり、エラーが少なくなります。何かを描き、理解しやすくするために、いくつかのモデリング言語の基本を学ぶことは良いアドバイスです。UMLはそれに最適です。

大きなものをデザインするための2つのアプローチがあります。下降することができます。つまり、高レベルの抽象化から始めて、下降して問題を絞り込みます。または、簡単に実行できる小さなことを実装することから始めて、次に上昇して、小さなモジュールをアプリに接続することもできます。

あなたはそれについての多くの情報をウェブ上で簡単に見つけることができます。それは一言で言えばです。さて、あなたの特定の質問のために。

  1. mainをグローバルスコープのままにします。個人的には、main.cppきれいに保つために別のファイルに残しておくこともありますが、どこに置いてもかまいません。

  2. グローバル変数を避けるようにしてください。定数が必要な場合は、それらを定義してもかまいません。そして、はい、単一のヘッダーファイルにすべての定義を含むアプローチはうまく機能します。ただし、10000の定義を持つファイルを、それらの1つだけを必要とする.cppに含めないように、意味によってそれらを分離することをお勧めします。

  3. 宣言する前にクラスを使用する必要がある場合は、前方宣言する必要があります。そうしないと、コンパイラーはクラスが存在することを認識しません。

  4. それぞれが#include基本的に対応するファイルのテキストをコピーペーストするため、インクルードの順序は重要です。したがって、あなたが#includeあなたのclass.h中にいる場合class.cpp、ヘッダーのテキストはプリプロセッサによってソースファイルにコピーアンドペーストされます。前方宣言の順序は、最初に使用する前に前方宣言を行う限り、実際には重要ではありません。

于 2012-08-13T11:53:42.773 に答える
4
  • C ++はOOP以上のものであり、複数のパラダイムです。OOフィルターを介してすべてを押そうとしないでください。これはC++に不利益をもたらします。いくつかの場所では、 「純粋な」OOに制限されていないため、C++はよりエレガントに物事を行うことができます。例えば、

  • main()がクラス内にあることはなく、常にグローバルスコープにあります。

  • 最も重要なルールは「一貫性」と「保守性」です。プログラムが「終了」し、いくつかのバグを修正したい場合は、後でプログラムをどのように見るかを考えてください。定数をどこで見つけて、最も簡単な方法を定義しますか?

  • シーケンスが重要な場合は#include、ヘッダーファイルが壊れています。各ヘッダーは、その中で宣言されているものに対して(少なくとも)自給自足である必要があります。

  • ヘッダーごとに1つのクラス宣言、実装ユニットごとに1つのクラス定義。ファイルとクラスの名前は同じです。本当に、これは私が交渉不可能だと考える唯一のルールについてです。クラスに関する情報を入手しなければならないことは、それgrepを行うよりも桁違いに不便ですfind

残りの部分は、実際には、C ++のすべての優れた本にあります。チュートリアルやQ&Aページに目を通すのではなく、本を使って作業する必要があります。

于 2012-08-13T12:01:13.157 に答える
1

わかりました...したがって、主な問題は、ファイルのOO編成を維持することのようです。何よりもまず、Google C ++スタイルガイドを読んでいない場合は、そうするように強くアドバイスします。私はまた、かなり明確で単純なこの以前の答えを見つけました

この助けを願っています

于 2012-08-13T11:51:35.303 に答える