Cのような手続き型言語とC++のようなオブジェクト指向言語の違いを理解しようとしています。私はC++を使用したことがありませんが、2つを区別する方法について友達と話し合っています。
C++には、オブジェクト指向の概念と、変数を定義するためのパブリックモードとプライベートモードがあると言われています。Cにはないものです。 Visual Basic.NETでプログラムを開発するときに、これらを使用する必要がありませんでした。これらの利点は何ですか?
また、変数がパブリックであれば、どこからでもアクセスできると言われていますが、Cのような言語のグローバル変数とどのように違うのかは明らかではありません。プライベート変数がローカル変数とどのように異なるのかもわかりません。
セキュリティ上の理由から、関数にアクセスする必要がある場合は、最初に関数を継承する必要があると聞いたことがあります。ユースケースでは、管理者はすべてではなく、必要なだけの権限を持つ必要がありますが、条件付きでも機能するようです。
if ( login == "admin") {
// invoke the function
}
なぜこれが理想的ではないのですか?
オブジェクト指向のすべてを実行するための手続き的な方法があるように思われるのに、なぜオブジェクト指向プログラミングを気にする必要があるのでしょうか。
これまでのすべての回答は、「cとc ++の違いは何か」という質問のトピックに焦点を当てていました。実際には、違いが何であるかを知っているように聞こえますが、なぜその違いが必要になるのか理解していないだけです。したがって、他の回答がOOとカプセル化を説明しようとしました。
あなたの質問の詳細に基づいて、あなたはいくつかのステップを取り戻す必要があると思いますので、私はさらに別の答えを取り入れたいと思いました。
C++やOOの目的を理解していません。なぜなら、あなたにとって、あなたのアプリケーションは単にデータを保存する必要があるだけだからです。このデータは変数に格納されます。 「なぜ変数にアクセスできないようにする必要があるのでしょうか?もう変数にアクセスできなくなります!すべてを公開するか、よりよくグローバルにすれば、どこからでもデータを読み取ることができ、問題はありません。」 -そして、あなたが正しい、あなたが現在書いているプロジェクトの規模に基づいて、おそらくそれほど多くの問題はありません(または問題はありますが、まだそれらに気づいていないだけです)。
あなたが本当に答える必要のある基本的な質問は、「なぜデータを非表示にしたいのですか?そうすると、データを操作できなくなる!」そしてこれが理由です:
新しいプロジェクトを開始し、テキストエディターを開いて関数の作成を開始したとします。何かを保存する必要があるときは(後で覚えておくため)、変数を作成します。物事をより簡単にするには、変数をグローバルにします。アプリの最初のバージョンは問題なく動作します。次に、機能を追加します。より多くの関数があり、以前に保存した特定のデータを新しいコードから読み取る必要があります。他の変数は変更する必要があります。あなたはより多くの関数を書き続けます。お気づきかもしれませんが(そうでない場合は、絶対に気付くでしょう)、コードが大きくなると、次の機能を追加するのに時間がかかります。そして、コードが大きくなるにつれて、以前は機能していたものを壊さずに機能を追加することがますます難しくなります。どうして?グローバル変数が格納しているallを覚えておく必要があり、変数のallが変更されている場所を覚えておく必要があるためです。そして、どの関数がwhat正確な順序で呼び出しても問題ないかを覚えておく必要があります。それらをdifferent順序で呼び出すと、グローバル変数がまだかなり有効です。これに遭遇したことがありますか?
典型的なプロジェクト(コード行)の大きさはどれくらいですか?現在、あなたのプロジェクトの5000〜50000倍の大きさのプロジェクトをイメージングしています。また、複数の人が働いています。チームの全員がどのようにして、これらすべての変数が何をしているのかを覚えている(または認識している)のでしょうか。
上記で説明したのは、完全に結合されたコードの例です。そして、時間の夜明け(1970年1月1日から始まると想定)以来、人間はこれらの問題を回避する方法を模索してきました。それらを回避する方法は、コードをシステム、サブシステム、およびコンポーネントに分割し、いくつの関数がデータにアクセスできるかを制限することです。 5つの整数と、ある種の状態を表す文字列がある場合、5つの関数だけが値を設定/取得すると、この状態での作業が簡単になりますか?または100の関数がこれらの同じ値を設定/取得する場合? OO言語(Cなど)がなくても、人々はデータを他のデータから分離し、コードの異なる部分の間に明確な分離境界を作成することに懸命に取り組んできました。プロジェクトが特定のサイズに達すると、プログラミングの容易さは「関数Yから変数Xにアクセスできますか」ではなく、「関数A、B、Cだけがあり、他の誰も変数Xに触れていないことを確認するにはどうすればよいですか」になります。
これがOOの概念が導入された理由であり、これが非常に強力な理由です。それらはあなた自身とあなたからあなたのデータを隠すことを可能にしますwant意図的にそれをするために、そのデータを見るコードが少ないほど、そこに存在する可能性が少なくなるので、次の機能を追加するとき、あなたは何かを壊す。これは、カプセル化とOOプログラミングの概念の主な目的です。これにより、システム/サブシステムをさらに細かいボックスに分割できます。プロジェクト全体の大きさに関係なく、特定の変数セットには50〜200行のコードでのみアクセスでき、それだけです。 OOプログラミングには明らかにはるかに多くの機能がありますが、本質的に、これがC++がデータ/関数をプライベート、保護、またはパブリックとして宣言するオプションを提供する理由です。
OOの2番目に優れたアイデアは、抽象化レイヤーの概念です。手続き型言語も抽象化を持つことができますが、Cではプログラマーが意識してそのようなレイヤーを作成する必要がありますが、C++ではクラスを宣言するときに自動的に抽象化レイヤーを作成します(この抽象化かどうかはユーザー次第です)値を追加または削除します)。あなたは抽象化レイヤーについてもっと読んだり研究したりするべきです、そしてもっと質問があれば、このフォーラムもそれらに答える以上に幸せになると私は確信しています。
うーん...多分バックアップして、オブジェクト指向プログラミングの基本的な意図のいくつかのアイデアを与えることを試みるのが最善です。オブジェクト指向プログラミングの目的の多くは、抽象データ型を作成できるようにすることです。間違いなくおなじみの本当に簡単な例として、文字列を考えてみましょう。文字列には通常、文字列の内容を保持するためのバッファ、文字列を操作できる関数(文字列内での検索、文字列の一部へのアクセス、部分文字列の作成など)が含まれます。文字列の(現在の)長さ、および(おそらく)バッファのサイズを追跡するので、(たとえば)文字列のサイズを1から1000000に増やした場合、より大きなメモリを保持するためにより多くのメモリが必要になるとわかりますコンテンツ。
これらの変数(バッファー、現在の長さ、バッファーサイズ)は文字列自体にプライベートですが、特定の関数に対してローカルですnot。各文字列には特定の長さのコンテンツがあるため、その文字列のコンテンツ/長さを追跡する必要があります。逆に、同じ関数(たとえば、部分文字列を抽出する)は、さまざまな時点で多くの異なる文字列を操作する可能性があるため、データを個々の関数に対してローカルにすることはできません。
そのため、文字列にプライベートなデータが作成されるため、文字列関数に(直接)アクセスできるだけです。外の世界はget文字列関数を使用して文字列の長さを指定できますが、文字列の内部について知る必要はありません。同様に、文字列を変更する可能性があります-ただし、文字列関数を介して変更を行い、文字列オブジェクトにローカルな変数を直接変更するだけです。
セキュリティに関する限り、これは類推としては妥当ですが、実際にはどのように機能するかnotであることに注意します。特に、C++でのアクセスは、具体的にはnotであり、オペレーティングシステムでのアクセスと同じ種類の要件を満たすことを目的としています。オペレーティングシステムはenforce制限を想定しているため、(たとえば)通常のユーザーできないは管理者用に予約された処理を実行します。対照的に、C++でのアクセス制御は事故を防ぐことのみを目的としています。設計上、簡単にバイパスすることができます。それらは、ファイルを読み取り専用にマークするのと同じ順序であるため、誤ってファイルを削除することはありません。ファイルを削除する場合、ファイルを読み取り専用から読み取り/書き込みに変更するのは簡単です。読み取り専用に設定すると、少なくとも1秒間考えて、decideでファイルを削除し、誤ったタイミングで間違ったキーを押すだけでファイルが誤って削除されないようにします。 。
OOP対Cは、あなたがこれまでに議論したことのどれでもありません。これは主に、意図せず(または場合によっては意図的に)互いに影響を及ぼさない(またはできない)領域にコードをパッケージ化することに関するものです。
Cでは基本的に、どこからでも任意の関数を実行できます。 OOPは、メソッドをクラスにグループ化し、それらを含むクラスを参照することによってのみメソッドを使用できるようにすることでそれを防ぎます。したがって、OOP多くの経験がなくてはならないということを伝えなくても、コードの配置が改善される可能性がはるかに高くなります。
適切に作成されたクラスは、少し「信頼の島」である必要があります。それを使用して、「正しいこと」を実行し、一般的な落とし穴からユーザーを保護すると想定できます。これにより、優れたクラスがビルディングブロックとなります。これは、機能と変数の束としてはるかに再利用可能であり、うまく機能するかもしれませんが、すべての醜い根性を示し、それらがどのように連携するか、どのように初期化する必要があるかを理解するように強制します。等。良いクラスはUSBプラグのようなものである必要がありますが、手続き上の解決策は、ワイヤ、チップ、スズ、はんだ付けビットの束のようなものです。
詳細に説明しなかった点の1つは、インターフェイス/実装の側面です。インターフェイスは動作を記述しますが、実現は記述しません。したがって、リストインターフェースはリストのconceptとその動作を記述します。メソッドの追加、削除、サイズ設定などが期待されます。今、このリストを実装する方法はたくさんあります。リンクされたリストとして、または配列バッファを使用して。 OOプログラミングの威力は、インターフェイスを使用することで、実装について知らなくても動作を推論できることです。内部変数またはメソッドにアクセスすると、この抽象化が破壊され、1つのリスト実装を置き換えることができませんそして、クラスを使用してコードに触れずに既存の実装を改善することはできませんでした。プライベート変数とメソッドが必要とされる主な理由の1つは、実装の内部の詳細を保護するため、抽象化はそのままです。
OOはさらに一歩進んでいます。ライブラリの場合、物事のインターフェイスを定義できますまだ存在していません。そのインターフェイスで動作するコードを記述できます。ユーザーは、インターフェイスを実装するクラスを記述し、ライブラリが提供するサービスを使用できます。これにより、手続き型プログラミングでは不可能な柔軟性を実現できます。
チューリングマシンですべてを行う方法、または少なくともCまたはC++プログラムが最終的にコンパイルするマシンコードのアセンブリ言語で行う方法があります。
したがって、違いは、コードが実行できることではなく、人々が実行できることです。
人々は間違いを犯します。たくさん。
OOPは、人間のコーディングミスの可能性があるスペースのサイズと確率密度を減らすのに役立つパラダイムと構文を導入しています。時には、特定のクラスのデータオブジェクト(そのオブジェクトに対して宣言されたメソッドではないなど)に対して誤りを違法にすることによって。時々、間違いをより冗長にしたり、言語の正規の使用法と比べて文体的に奇妙に見えることによって。場合によっては、矛盾した使用法や絡まった使用法(パブリックとプライベート)の可能性がはるかに少ないインターフェースを要求することによって等.
プロジェクトが大きいほど、ミスの可能性が高くなります。小さなプログラムでのみ経験した場合、新しいコーダーにさらされないかもしれません。したがって、なぜOOP=であるかについての潜在的な困惑は価値があります。
あなたの質問は、違いではなくOOPの目的についてのようです。投稿の概念はカプセル化であり、カプセル化はCHANGEをサポートするために存在します。他のクラスが内部にアクセスしている場合、変更が困難になりますOOPでは、他のクラスとのやり取りを許可するインターフェース(パブリックメンバー)を提供し、内部を非表示にしてそれらを安全に変更できるようにします。
プライベート変数にどこからアクセスしてもアクセスできませんが、パブリック変数にはアクセスできますが、パブリックをグローバル、プライベートをローカルにしてみませんか?パブリックとプライベートの実際の使用はどうですか?どなたでもご利用いただけるとは言わないでください。条件をつけて電話をかけてみませんか?
アプリケーションで複数の文字列が必要にならないようにしてください。また、ローカル変数が関数呼び出し間で保持されることを願っています。これらはアクセシビリティの点では同じかもしれませんが、寿命やその他の使用法の点では同じですか?それらはまったく同じではありません。
多くの人が言ったように、コンパイルされたプログラムはバイナリコードに変換され、バイナリ文字列は整数を表すために使用される可能性があるため、プログラムは最終的には単なる数値になります。ただし、必要な数を定義するのはかなり難しい場合があるため、高水準のプログラミング言語が登場しました。プログラミング言語は、最終的に生成するアセンブリコードの単なるモデルです。プロシージャ指向のプログラミングとOOプログラミングの違いを、コンテキスト指向プログラミングに関するこの非常に素晴らしいペーパーを使用して説明します http://www.jot.fm/issues/issue_2008_03/article4 /
この図からわかるように、ペーパーに描かれているように、手続き型プログラミングは、計算単位と名前を関連付けるための1つの次元しか提供しません。ここで、プロシージャコールまたは名前は、プロシージャ実装に直接マップされます。図-aでは、m1を呼び出すだけで、プロシージャm1の唯一の実装を呼び出すことができます。
オブジェクト指向プログラミングは、手続き型プログラミングの次元に名前解決のもう1つの次元を追加します。メソッドまたはプロシージャ名に加えて、メッセージディスパッチでは、メソッドを検索するときにメッセージレシーバーが考慮されます。図-bでは、メソッドm1の2つの実装を示しています。適切なメソッドの選択は、メッセージ名m1だけでなく、実際のメッセージの受信者(ここではRy)にも依存します。
これにより、カプセル化とモジュール化が可能になります。
Figure-cは最後に、サブジェクト指向プログラミングがオブジェクト指向メソッドディスパッチをさらに別の次元で拡張することについてです。
これが、OOPを別の視点から考えることの助けになったことを願っています。
(+ 1)理解できないことについて質問することは、たとえばかげて聞こえても、良いことです。
違いはオブジェクトとクラス指向プログラミングです。「プレーンC」はデータと関数で動作します。「C++」は「オブジェクトとクラス」の概念に加えていくつかの関連する二次的な概念を追加します。
ただし、私は「C++」の前に「プレーンC」を学ぶことを開発者に推奨しています。または、「Object Pascal」の前の「Procedural Pascal」。
多くの開発者は、学生は1つだけを教えるべきだと考えています。
たとえば、O.O。を取得せず、 "Plain Structured C"のみを教える古い教師。
あるいは、O.O。のみを教え、「プレーンC」は教えない「ヒップスター」の教師。または両方、指導順序を気にせず。
むしろ学生には「構造化プレーンC」と「オブジェクト指向C(C++)」の両方を教えるべきだと思います。最初は「プレーンC」、その後は「C++」。
実際には、両方のパラダイム(および「機能的」などの他のパラダイム)を学ぶ必要があります。
構造化プログラムを1つの大きな「オブジェクト」として考えると、役立つ場合があります。
また、名前空間(「モジュール」)にも重点を置く必要があります。両方の言語で、多くの教師はそれを無視しますが、重要です。
一言で言えば、プロジェクト管理。つまり、C++は、自分のコードが他の人によってどのように使用されるかについてのルールを強制するのに役立ちます。 550万行のプロジェクトに取り組んでいますが、オブジェクト指向プログラミングは非常に役立ちます。別の利点は、私(および他のすべての人)が特定の規則に従い、コンパイル時に小さなエラーをキャッチできるようにするコンパイラーです。理論上の利点もすべてありますが、私は日常の実用的なことに焦点を当てたかっただけです。結局のところ、すべてがマシンコードにコンパイルされます。