web-dev-qa-db-ja.com

STLはOOで実装されていますか?

Adaptor、STLに実装されたIteratorなど、いくつかの設計パターンがあります。

これは、STLがOOコンセプトで実装されていることを意味しますか?
OOとC++のテンプレート部分の関係は何ですか?

OOを正当化する仮想メンバー関数がテンプレートと矛盾していることを学びました、これは正しいですか?

8
upton

まず、「STL」は正式な用語ではなく、コンテナがなかったときにC++標準ライブラリに含めることが提案されたライブラリの名前です。それは本質的にコンテナーとアルゴリズムのテンプレートを提供します。

現在、これらのコンテナとアルゴリズムのテンプレートは...テンプレートなので、必要に応じて型を生成します。ユーザーの観点からは継承に依存していません。

ただし、標準ライブラリは、実装ではなく、基本的にライブラリのインターフェイスを指定します。多くのSTL実装は、実装でオブジェクト指向を少し使用しますが、実装のソースコード(本質的にはテンプレートコードであるため公開する必要がある)に飛び込まない場合、ユーザーには表示されません。

OOを正当化する仮想メンバー関数がテンプレートと矛盾していることを学びました、これは正しいですか?

いいえ、それらは非常に異なる長所と短所のセットを提供する直交概念です。実際、C++では、そのような言語を使用する主な利点の1つは、両方を使用できることと、一方を使用しても他方を使用してキャンセルしないことです。それも非常に大きな利点です。たとえば、C++で最も興味深いイディオムの1つは、テンプレートと継承の両方を使用する [〜#〜] crtp [〜#〜] です。継承部分を使用すると、基本クラスとして、共通の動作とデータを使用していくつかの型を拡張できます。テンプレートパーツでは、子ごとに特定の基本クラスを生成する必要があるため、CRTPクラスを基本として使用して、すべてのクラスへのポインターを持つことはできません。これは非常に便利で、本来あるべきではないところに継承をいじることを許しません。

また、イベントタイプやリスナータイプを認識せず、適切なランタイムタイプに対応する適切な内部タイプを生成できる内部動的コードと静的コードを組み合わせた非常に一般的なイベントディスパッチシステムも実装しました。

そして、それがポイントです。常に「オブジェクト指向」を必要とするわけではありません。実際、ほとんどの場合、それをまったく必要とせず、いくつかのタイプを定義し、それらをある種の抽象エンジン(構成)の別の部分として直接使用する必要があります。テンプレートとも呼ばれる一般的なコードが常に必要なわけではありません。関数を一般化して、いくつかの無関係な型に適用することが必要になる場合があります。それらが関連している場合は、代わりに基本クラスを使用でき、テンプレートは必要ありません。

それらは異なる利点と完全に異なるコストを持っているため、複雑な問題を解決するために組み合わせるのに適しています。

STLは、ランタイムオブジェクトの階層ではなく、特定のタイプに関連するタイプ(コンテナ)と関数(アルゴリズム)を提供することに関する問題の良い例です。標準ライブラリでは、ストリームはオブジェクト指向に一般的な方法で作成されます。これは、さまざまな動作/容量を組み合わせたサブストリームクラスを定義できるようにさまざまなことを行うストリームクラスの階層です。そこでは、オブジェクト指向は有用ですが、STLのようになりたいと考える人もいます(私はこのテーマの専門家ではありません)。

だから、それらをドライバーとハンマーのような非常に異なるツールと考えてください。 C++では、1つのツールだけを念頭に置いて考えることはできません。

11
Klaim

実際、STLはGeneric Programmingパラダイムを主流に導入しました。

オブジェクト指向プログラミングパラダイムについて(一部の教授から)15年前に教えられたとき、3つの重要な柱はカプセル化、継承、およびポリモーフィズムです(今日、後者はおそらく次のように修飾されるべきです) runtime polymorphism)、一方 Wikipediaは現在リストデータの抽象化、カプセル化、メッセージング、モジュール化、多態性、継承定義としてOOP特性。もちろん、STLはカプセル化などの一部を使用しますが、構造化プログラミングパラダイムの特性である関数も使用します。しかし、誰もSTLを主張しませんis 構造化プログラミング

C++の最も強力な機能の1つは、多くのプログラミングパラダイム(構造化、オブジェクト指向、ジェネリック、関数型プログラミングなど)をサポートしていることと、それらを混ぜて混ぜると最も明るくなるということです。

8
sbi

STLPortインタビュー からAlexander Stepanovを引用するには:

STLはオブジェクト指向ではありません。オブジェクト指向は、人工知能とほぼ同じでっちあげだと思います。 OO people。[...]私はOOP哲学的に不健全だと思います。すべてがはオブジェクトです。たとえそれが真実であるとしても、それほど興味深いことではありません。すべてがオブジェクトであると言っても、まったく何も言っていません。OOP方法論的に間違っています。

とはいえ、個々の実装は継承と多相性を使用して場所で実行できます。たとえば、iteratorからconst_iteratorへの暗黙的な変換をサポートするために、iteratorconst_iteratorから派生した実装を見てきました。導出はではありませんただし、設計の特徴であるか、設計で必要です。

結論:オブジェクト指向のコードを使用してSTLの一部を実装することができますが、STL自体の設計は(特に)オブジェクト指向ではありません。

7
Jerry Coffin

いいえ、私はSTLは特にOOではないと思います。それが関数型プログラミングスタイルにマッピングされているとすれば、特に:

  • std :: algorithmsはメソッドではなくフリー関数です
  • 彼らはしばしば関数オブジェクトをとります::高次関数です
  • 彼らはあらゆるコンテナで動作します
  • std :: transform はマップ、X_if関数はフィルター、 std :: accumulate は折りたたみ/縮小

同様に、コンテナー自体がモナドであると主張することもできます

  • テンプレートのインスタンス化は型構築です
  • シーケンスには少なくともユニットコンストラクタがあります。 vector<string>(1,"Foo")
  • fmapは std :: transform
  • バインドまたは結合、あるいはその両方が実装可能です(そのままでは提供されません)
  • bind/joinの合理的な実装はモナドの法則に適合します

他の質問については、C++のOOパーツとテンプレートパーツは別々であり、仮想関数はテンプレートを持つことを排除しません。STLの場合、デザインは仮想関数の使用を選択しません。 。

3
jk.

OOPは悪名高く悪名高い用語であり、OOPを構成するものについて十分なコンセンサスがないため、しないこと。

Java人の観点から見ると、C++のアルゴリズムとコンテナライブラリはランタイムのポリモーフィズムを処理せず、クラス継承を使用せず、構文がOOP-yに見えません。

一方、 機能するプログラミング担当者に尋ねる の場合、答えは「はい」です。

ウィキペディアの方法は次のとおりです defines OOP:

オブジェクト指向プログラミング(OOP)は、アプリケーションとコンピュータープログラムを設計するために、「オブジェクト」(データフィールドとメソッドとそれらの相互作用で構成されるデータ構造)を使用するプログラミングパラダイムです。プログラミング手法には、データの抽象化、カプセル化、メッセージング、モジュール性、多態性、継承などの機能が含まれる場合があります。最近のプログラミング言語の多くは、少なくともオプションとしてOOPをサポートしています。

これらはすべて、C++の標準ライブラリ、特にコンテナとアルゴリズムを扱う部分で実現または支援されています。特に、アルゴリズムはカプセル化と抽象化(したがってモジュール性)を強化し、テンプレートを使用することで多態性になります。

3
Konrad Rudolph

私の意見では、STLはオブジェクト指向ではなく、反復可能なコンテナのアルゴリズムに関するものです。

これは、アルゴリズムを使用するために実装される共通のインターフェース(イテレーター)を定義します。

C/C++イテレータは、JavaおよびC#では列挙子/列挙可能と呼ばれます

多分STLはOOよりもアスペクト指向です。

1
k3b

オブジェクト指向を正当化する仮想メンバー機能を学びました

一体どこで聞いたの?

オブジェクト指向の重要な原則は、カプセル化と抽象化です。 virtual関数は、それを実現するための1つの手段にすぎません。実際のオブジェクトの向きにはまったく必要ありません。実際、テンプレートは完全に適切な手段です。それは継承ではないかもしれませんが、それでも一種の多態性です。そして、いくつかのクラスはどちらも必要としません。

標準ライブラリのコンテナは完全にオブジェクト指向です。それらはインターフェースからのすべての不必要な詳細をカプセル化し、実装を合理的に可能な限り最大限に抽象化します。

1
DeadMG