C ++はOOPに適していませんか?[閉まっている]


12

C ++はオブジェクト指向プログラミングに適していないことを、ここでの質問に対する回答の1つで(どこにあるか覚えていない)読みました。あなたはその機能またはそのようなものを利用できるが、純粋にOOPの意味ではないという言及がありました(私は実際にその人の意味を本当に理解していませんでした)。

これにはいくつかの真実があります。もしそうなら、なぜですか?


これを探していますか?stackoverflow.com/questions/1635583/…?または、このjavaworld.com/javaworld/jw-04-2001/jw-0406-java101.htmlですか?
S.Lott

5
OOPは明確に定義された用語ではないため、C ++が適切かどうかを議論することは無意味です。
-zvrba

回答:


31

で説明したように、「オブジェクト指向」という用語でアランケイは本当に何を意味しましたか?、Alan Kayは、メッセージの受け渡しがOOPの重要なビットであると考えましたが、「クラスを持つC」(後にC ++になりました)には欠けているビットです。C ++は動作が少しだけの構造体ですが、SmalltalkまたはObjective-Cのオブジェクトは、送信されるメッセージをどう処理するかを決定できるという点で「インテリジェント」です。Smalltalk風のオブジェクトが実装されていないメッセージを受信した場合、それを遅延的に追加したり、別のオブジェクトにメッセージを転送したり、任意のことを実行したりできます。

オブジェクト指向の方法でC ++が提供するのは、virtualメソッドと、それらのメソッドが呼び出される方法に関係するポリモーフィズムです。コンパイラは、class仮想メソッドを持つデータ型(または)を検出すると、各仮想メソッドのスロットを持つvtableを構築します。仮想メソッドを実装するサブクラスは、実装を正しいスロットに配置するため、クライアントコードは、特定の関数に至るまで解決するのではなく、実行するコードを探す仮想テーブルの場所を知るだけで済みます。つまり、C ++は事実上複数のディスパッチの形式を持ってますが、すべてコンパイラに実装されており、Smalltalk風のシステムほどの能力はありません。

メッセージの受け渡しをOOPの基本と考えると、C ++でそれを行うことはできます、決して簡単ではありません。OTOH OOPを使用して、データをそのデータに作用する関数に関連付けることを意味する場合、C ++で問題ありません。


8
+1-しかし、とにかく関数呼び出しはメッセージを渡すための合理的な方法だといつも思っていました。確かに、それはすべてを高レベルで修正するのではなく、低レベルの基盤です。しかし、アクティブオブジェクトパターンは、その基盤から構築することが可能であることを示しています。
Steve314

6
C ++のが、Java、C#、Object Pascalの、などに限らず適用され、それがWindows APIのメッセージングシステムは、アランは、OOPの中で最も重要なこととして、どのような意味であるとされて終わるこれは、そう、それはDelphi(デルファイ)によって処理され、特別な方法
トリニダード

@trinidadは正しいですが、C#が実際に動的な解決をサポートしていることを除きます。私たちのOOPの考え方は、メッセージの受け渡しの欠如を回避するために時間とともに変化してきたと言ってもいいでしょう。ベンダーは、自社のテクノロジは間違いなくOOPであると言うことで間違いなく助けました

@ steve314はい、そうです。実際、ObjCはこのように動作します。メッセージ送信は、メソッド関数を検索して呼び出す関数呼び出しに変換されます。私はメッセージの受け渡しを理解しているので、重要なのは二重ディスパッチです。

1
@Paul:Win32 APIの使用経験は限られていますが、わかりません。オブジェクトのサイズが可変で、オブジェクトの大きさを決定し、メモリを割り当て、再度呼び出すために最初にルーチンを呼び出す必要があるAPIは、美しさのテストに失敗します。
デビッド

26

この種の議論は、たちが問題ではないと思うかのように、聖書の解釈、聖書やアメリカ憲法の意味を議論する人々、そして原作者の意味のように聞こえるので、私を悩ませます。

ほら、アラン・ケイは賢い人でした。そして彼は良いアイデアを持っていて、他のたくさんの良いアイデアとこすり合い、Smalltalkや他の言語でその実現を見つけました。

彼は救世主ではなく、OOPは1つの真のプログラミングパラダイムではありません。

多くの人にとって、それは良い考えです。C ++には、OOPの考え方に基づいた良いアイデアがありますか?もちろんそうです。


8

カプセル化、継承、およびポリモーフィズムを意味するようにOOPを定義する場合、C ++ OOPをサポートします。

ただし、C ++はOOPにはあまり優れていません。理由の1つは、ポリモーフィズムがヒープ割り当てオブジェクトに依存することが多いことです。ヒープ割り当てオブジェクトは、(スマートポインターの使用にもかかわらず)ガベージコレクション言語での作業がより自然です。

ただし、C ++が優れているのは、汎用プログラミングです。C ++を使用すると、テンプレートベースの関数型プログラミング手法により、効率の高い汎用コードを簡単に作成できます。


4

C ++はSimulaからOOP機能を借りました。Simula開発者IIRCの1人以上は、C ++は彼らが念頭に置いていたものではないとコメントしました。

C ++には抽象化のための優れたツールがありますが、オブジェクト指向言語というよりは混合パラダイム言語です。オブジェクト指向機能はありますが、「厳密なOOP」ではない選択肢があります。

C ++で得られるいたずらな「オプトアウト」の1つは、メソッドの遅延バインディングではなく早期バインディングを使用することです。これが可能であるだけでなく、これがデフォルトです。Javaでは、「最終」は関連していますが、いくつかの点でよりクリーンです(些細なパフォーマンスのオーバーヘッドを回避するだけではない方法で意図を指定します)、そしてそれはデフォルトではありません

いくつかの点で、C ++はまだ実験中の初期の実験の兆候を示しています。それでも、他のOOP言語では得られない多くの利点を備えた、優れたツールです。


2
C ++は非OOPを許可し、C ++はOOPを許可します。一部の言語はオブジェクト指向であるため、OOPを許可する必要があるため、C ++はオブジェクト指向言語です。
トリニダード

1
Smalltalkの名声のAlan Kayは、「オブジェクト指向」という用語を生み出したとき、C ++は彼が念頭に置いていたものではないと言ったと思います。C ++は「C with Classes」として始まり、CにSimulaクラスを移植し、完全に中断することはなかったので、初期の実験のように見えるのも不思議ではありません。
デビッドソーンリー

1
@Trinidad:ANY言語はOOPを可能にします。昔ながらのC言語でかなり多くの素晴らしいOOコードを見てきました。はい、すべての仮想メソッドテーブルを手作業で定義するのは苦痛ですが、言語では明らかに許可されています。
1月Hudec

4

すべてを強制的にクラスの一部にすることは、必ずしもすばらしいオブジェクト指向コードを生み出すとは限りません。

貧しい手続き型プログラマーにJavaでプログラミングするように依頼すると、おそらくどこかにクラスを取り、静的なメインメソッドを与えて、そこに1000行のコードを挿入します。私はそれを見たことを知っています。

Javaにはswitchステートメントがあります。私はswitch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }C ++とJavaコードの両方でなどを見てきました。

C ++は多くのオブジェクト指向の概念をサポートしていますが、その標準はそれによって定義されていませんが、私はあなたの目的が何であるかに大きく依存すると思います。

C ++の主な「貧弱な」セマンティックは、クラスのコピー構築を許可し、それによってオブジェクトが別のクラスに変換されることです。これを無効にすることはできますが、関数から返すことはできません。幸いなことに、これはC ++ 0xで対処されています。


3

OOPは、すべてがクラスに属しているか、クラスに属していることを確認するだけではありません。「純粋なオブジェクト指向」言語で非オブジェクト指向コードを書くことは完全に可能です。たとえば、 "main"はグローバル関数であるとしばしば指摘されますが、静的mainメソッドを含むためだけにクラスを作成することは、オブジェクト指向ではありません。

C ++は、さまざまなものが混在する場合に最適に機能します。これは驚くべきことではありません。それが最も良いものが最もうまく機能する方法だからです。多くの場合、OOPはこれらの非常に便利なツールの1つです。


2

C ++はOOPに使用できますが、Smalltalkのような「純粋」ではありません。C ++を使用すると、非OOPを実行できます。


2

私は感情に同意しませんが、C ++の型システムは純粋なOOPではなく、「すべてがオブジェクトである」ことではないのは事実です。(特に)数字は、たとえばSmalltalkのように簡単に拡張できません。たとえば、「2 + 2」の意味を再定義することはできません(ただし、「two + two」の意味は再定義できます)。

しかし、ほとんどの人がおそらく意味するのは、多くの人が非オブジェクト指向のコードをC ++で記述しますが、「OOP」言語を使用しているため、オブジェクト指向であると信じているということです。それは真実ではない。しかし、私の意見では、Smalltalkで恐ろしい命令型コードを書くことができ、C ++でのきちんとしたOOP設計よりも優れているわけではありません。


1

C ++に対するAlan Kayの完全に有効な異議は、C上のマクロ言語であるということでした。

「メッセージの受け渡し」の概念は、クラスのインスタンスがメモリに保持され、呼び出し可能なメソッドを公開するという考え方にすぎません。C ++では、関数へのポインターを保持するvtableを使用して、メッセージの受け渡しが*シミュレートされます。

メッセージの受け渡しはC ++には存在しないと言うと、メッセージの受け渡しはsmalltalkやJavaのような他の言語の不可欠な部分であるということです。

これは高度にセマンティックな言語設計の議論であり、質問者の経験レベルを少し超えていると思われます。

C ++を嫌う理由は1000ありますが、C ++を愛する理由はほとんどありません。

完璧なハンマーと完璧な釘を探すのではなく、構築するのに最適な家を見つけてから、経験が必要な適切なツールを見つけてください。

また、システムプログラミングでアランケイが恐れているのは「純粋なOOP」ではないことを覚えておくことが重要です。これは実際にはC ++の強みです。それぞれ自分自身に...


1
Objective Cは、C上でマクロ言語としても開始されましたが、オブジェクト指向言語です。
1月Hudec

1

私の見解では、それは定義の問題ではなく、ユーザビリティの問題ではありません。

オブジェクトは、複雑なプログラムの読み取り、書き込み、および推論を容易にするための抽象化です。実用的なプログラマーにとって、言語が「オブジェクト指向」の特定の正式な定義(競合するものがあるようです!)のすべての基準を満たしているかどうかは、提供するツールが考えるのに適しているかどうかほど重要ではありません前述のオブジェクトの観点からプログラムを作成します。つまり、OOPの想定される生産性のメリットを実際に享受します。

C ++では、オブジェクトはひどく漏れやすい抽象概念であり、多くの場合、プログラマーは、それらのオブジェクトがメモリ内でどのように構成されているかに関する厄介な問題を抱えることになります。たとえば、C ++ Frequently Questioned Answersは、この批判を(とりわけ)提供しています。

C ++以外のOOシステム、およびC ++を「OO」と見なす特別な方法で解釈される「カプセル化、継承、ポリモーフィズム」トリニティ以外のOO定義に習熟することは、開業医にとって非常に有益です。たとえば、境界チェックやガベージコレクションがない環境はオブジェクト指向環境ではないという主張は、C ++に慣れている人にとってはとんでもないことです。しかし、多くの観点から、それは非常に理にかなっています。誰かがオブジェクトを上書きできる場合、「カプセル化」はどこにありますか?オブジェクトを破棄すると、ぶら下がり参照やメモリリークが発生する可能性がある場合、システムはどのように「オブジェクト指向」であるか ?特定の場所と時間にどのようなオブジェクトが配置されているかを伝える機能はどうですか?あなたはソフトウェアがオブジェクトで動作すると言います-それらはどこにありますか?そして、見つけられない場合、ソフトウェアをどのようにデバッグするのですか?

C ++はオブジェクト指向ですが、不快で不完全です。ユーザーは、データが誤ったビットではなく、実際のオブジェクトのように振る舞うように多くの努力を払う必要があります。とは言っても、多くのコードはその寿命にわたってC ++で記述されており、そのほとんどはクラスと動的ディスパッチ使用しているため、実際のOOPに使用できることは自明のことです。


真剣な答えであるはずのFQAを参照する場合は-1。FQAは、歪み、半分の真実、誤解の巣です。
デビッドソーンリー

@DavidThornley 特定の引用は、歪み、半分の真実、または誤解ですか?
アレックスP

そこのどこかに。OO言語には境界チェック(とにかくC ++標準コンテナーに組み込まれることもある)とガベージコレクション(スマートポインターはプリミティブガベージコレクション)が必要であるという主張は、強制的で不誠実です。オブジェクト指向ではないぶら下がり参照を許可する言語に関する文は、明らかにBlatant Assertionによる証明です。私は「どんな種類のオブジェクトを伝えることができるか」に戸惑っています。ポインタ型は、仮想動作のないオブジェクトに対してはそれを提供し、RTTIは仮想動作のあるオブジェクトに対してはそれを処理します。
デビッドソーンリー

@DavidThornley FQAの主張は、有用なオブジェクト指向言語にはこれらの要素が必要だということです。これは、尋ねられている質問と一致しています(C ++は「適切ですか?」)。必要最低限​​の定義に関する主張は、実際にはそれを解決するものではないと思います。プログラムはそのガベージを喜んでデータとして解釈し、その後、範囲外のアドレスにヒットするか大規模なエラーが発生するまで、他のガベージデータへのガベージポインタに従います。
アレックスP

ただし、引用は少なくとも境界チェックやガベージコレクションのない言語はオブジェクト指向ではないという主張を強く示唆しており、必要に応じてこれらのものがC ++にあるという事実を無視しています。言語が特定のクラスのエラーを防止するかどうかの問題は(何らかの理由で)オブジェクト指向かどうかとは直交します。
デビッド

-1

ここにグラハム・リーが最も賛成票を投じた理由があります。繰り返しますが、C ++クラスは、メッセージの受け渡しを実行しないという意味で、実際にはオブジェクトではないようです。これが、C ++やoopを学んでいる人を大いにつまずかせるものだと思います。人々は、オブジェクト指向は「これ」であると言われ、C ++はそれを違うやり方で行うと言われます。さて、C ++はOOPをこれまでとは異なりませんでした。このように考えると、C ++クラスの意味を理解することはできません。つまり、抽象化と動的な振る舞いを組み込むことにより、手続き型パラダイムを単に改善しただけです。したがって、C ++クラスは基本的に手続き型であり、手続き型のパラダイムを改良したものであるか、C構造体のより高度なバージョンです。


あなたの議論の実際の支持理由はありますか?あなたは主張をして、意見が違う人は間違っているか、違う見方をしたり、オブジェクト指向の正確な定義を共有していると考えを変えると主張しているようです。
デビッドソーンリー

けっこうだ。この記事を読むことができます。私が言っていたことは、c ++は厳密なアラン・ケイの意味での「オブジェクト指向プログラミング」ではないということだと思います。ただし、OOPを動作を伴うデータ構造として定義する場合、c ++をOOPと見なすことができます。私の考えでは、C ++クラスをより高いレベルの手続き型プログラミング抽象として見る方がより正確です。c ++クラスは、Kayスタイルオブジェクトよりもはるかに効率的ですが、同時実行性については悪化します。個人的には、c ++クラスは素晴らしいデザインだと思います。
annoying_squid

1
リンクをお寄せいただきありがとうございますが、アランケイの意味を説明するだけです。さらに、Smalltalkは一般に最初のOO言語と見なされることに同意しません。Wikipediaは、それがStroustrupを組み合わせてクラスを含むCを形成する2つの言語の1つであるSimulaであることに同意します。C ++クラスはオブジェクトテンプレートよりも高レベルの手続き型プログラミングの抽象化であるというあなたの主張に興味がありますが、なぜあなたはそのように考えるのか理解できません。
デビッドソーンリー

私たちがそれに同意できれば、オブジェクト指向はおそらく主観的な用語です。しかし、Kayオブジェクトは、各オブジェクトがメッセージの受け渡しを通じて相互作用するミニコンピューターのような役割を果たしているという意味で、コードを分離し、並行モジュール性を導入するより自然な方法であると考えています。このモデルでは、プログラムのロジック全体をセルとメッセージとして表現できるように、「中間」のコードをほとんどまたはまったく必要としません。比較すると、「クラス」の使用には通常、間に手順的なグルーコードが必要です(真のモジュール性はありません)が、利点はクラスがはるかに効率的であることです。
annoying_squid

-1

スティーブ・イェッジが一番いいと言った

C ++は、最も知覚力が低いという非常に現実的な意味で、地球上で最も愚かな言語です。それ自体は知りません。

C ++のオブジェクトシステムはコンパイル時に非常にハードワイヤードで固定されているため、メッセージパッシング、イントロスペクション、リフレクション、動的ディスパッチ、レイトバインディングなどを含むOOPの元の概念とは非常に異なります。C ++とSmalltalkの共通点は、少しの語彙だけです。


C ++は最も感覚の低い言語ですか?言語が感覚的であるとはどういう意味ですか?リフレクション機能がないという意味であれば、それはごく一般的なことであり、C ++を群衆の中から選ぶことはありません。
デビッドソーンリー

2
彼はそれを「最高」と言ったとどうして言えますか?そのランダムな引用の意味がわかりません。
user16764

この種のことを言う+1は、C ++バッシャーバシャーから多くの軽視を取得しますが、言わなければならない-あなたは、水平方向のものを処理するジェネリックを持っていないので、リフレクションなしで本当にOOPをすることはできません(側面)-ライフサイクル(アクティベーション、廃棄)、一般的なエラー処理、一般的なプロキシ、一般的なシリアル化、一般的なタスクの並列処理-これらはコードを汚染し、SoCを破壊します。
vski

ありがとう。反省のない言語はOOPの良い例ではないと言って-3になったとは信じられません。
ジョンクロマティー

1
@JohnCromartie、あなたの答えのその点について詳しく説明していただけますか?
ジェレミーハイラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.