ソースコードなしで C++ ライブラリからクラスを拡張することは可能ですか? 継承を使用するには、ヘッダーがあれば十分でしょうか? 私はC++を学んでいて、理論に取り掛かっています。これをテストしますが、方法がわかりません。
4 に答える
簡単な答え はい、間違いなくできます。
長い回答: 警告: 次のテキストは、敏感な OOP インテグラリストの子供を傷つける可能性があります。あなたがそのような人の一人であると感じている、またはそうであると感じている場合は、この答えから離れてください。
秘密を明かしましょう: STL コードは、ヘッダーとライブラリが付属する通常の C++ コードにすぎません。コードができる (そしておそらくできる) のとまったく同じです。STL の作成者は、あなたと同じプログラマーです。それらは、コンパイラに関して特別なものではありません。それに対する超大国はありません。彼らはあなたがあなたと同じようにトイレに座って、まさにあなたがしていることをします。それらを過度に誤解しないでください。
STL コードは、独自に記述したコードとまったく同じ規則に従います。オーバーライドされたものは、ベースの代わりに呼び出されます。それが仮想の場合は常に、仮想でない場合は、参照ポインターの静的な型に従ってのみ、他のすべてのように呼び出されます。 C++ コードの一部。それ以上でもそれ以下でもありません。
重要なことは、STL の命名規則とセマンティクスを尊重する設計上の問題を覆さないことです。これにより、コードをさらに使用するたびに、10 年後にコードを読んで特定の決定を覚えていない自分自身を含め、人々の期待を混乱させることはありません。
たとえば、オーバーライドstd::exception::what()
は説明的な永続的な C 文字列を返さなければならず (STL ドキュメントが言うように)、予期しない他のあいまいなアクションを追加してはなりません。
また、ストリームやストリーミング オペレータのオーバーライドは、設計全体を考慮して行う必要があります (ストリームをオーバーライドする必要があるのか、ストリームバッファだけをオーバーライドする必要があるのか、それとも、影響を受けたロケールに特定のファセットを追加するだけなのか?):クラス」ですが、周りのものとどのように機能するかを適切に理解するために、そのすべての「世界」の設計。
最後になりましたが、最も物議を醸す側面の 1 つは、コンテナーと、仮想デストラクタを持たないすべてのものです。
私の意見では、「古典的な OOP ルール: 仮想デストラクタを持たないものを派生させてはならない」というノイズは誇張cow
されhorse
すぎているということですsaddle
。
暗黙的に std::string に変換でき、さらに何かを持っている std::string とまったく同じインターフェイスを持つ文字シーケンスを管理するクラスが必要な場合 (本当に本当に必要な場合)、次の 2 つの方法があります。
- 良い良い女の子がすること
std:string
をし、それらを呼び出すだけの関数で112(はい:100以上あります)メソッドをすべて埋め込み、書き直して、別の良い良い男の子のプログラマーのコードとの結婚にまだ処女であることを確認してください、 また ... - これには約30年かかり、40歳の処女になる危険があることを発見した後、プログラマーはもう興味を持っていません。より実用的になり、処女を犠牲にして
std::string
. あなたが失う唯一のものは、統合主義者と結婚する可能性です. そして、それが必ずしも問題ではないことを発見することさえできます: 彼に殺されるリスクから遠ざかっています!
あなたが注意しなければならない唯一のことは、std::string
あなたの派生物はポリモーフィックではないので、そのようなものになることはほとんどないので、デストラクタを含むあなたのメソッドを呼び出すことを期待しstd::string*
たりstd::string&
参照したりしないでください。yourstring
まったく同じルールに従うだけです。しかし...ねえ、暗黙の変換演算子を埋め込んで書くと、まさにその結果が得られます。それ以上でもそれ以下でもありません!
ルールは簡単です。デストラクタを仮想化しないでください。また、OOP 用に設計されていないもので「OOP 置換原則」が機能するふりをしないでください。そうすれば、すべてがうまくいきます。
すべての OOP インテグラリストがペースで永遠の睡眠を要求することで、コードは機能しますが、100 以上の std::string メソッドを埋め込むためだけに書き直しています。
はい、クラスの宣言はそれから派生するのに十分です。
ライブラリに対してリンクすると、残りのコードが取得されます。
はい、標準 C++ ライブラリのクラスを拡張できます。ヘッダーファイルで十分です。
いくつかの例:
std::exception
クラスを拡張してカスタム例外を作成する- ストリーム ライブラリを拡張してアプリケーションでカスタム ストリームを作成する
ただし、注意すべきことの 1 つは、. を持たないクラスを拡張しないことvirtual destructor
です。例はstd::vector
、std::string
編集:このトピックに関する別のSOの質問が見つかりました継承によるC++標準ライブラリの拡張?
そのクラスから継承するには、ヘッダー ファイルがあれば十分です。
C++ プログラムは、次の 2 つの段階でビルドされます。
- コンパイル
コンパイラは、型の定義を探し、プログラムの言語が正しいかどうかをチェックします。これにより、オブジェクト ファイルが生成されます。 - リンク
コンパイルされたオブジェクト ファイルがリンクされて、実行可能ファイルが形成されます。
したがって、ヘッダー ファイル (コンパイルに必要) とライブラリ (リンクに必要)がある限り、クラスから派生できます。
ただし、そのクラスが本当に継承を意図しているかどうかに注意する必要があることに注意してください。例: 非デストラクタを
持つクラスがある場合、そのクラスは継承用ではありません。virtual
すべての標準ライブラリ コンテナー クラスと同様です。
要するに、クラスのインターフェースを持つだけで派生に十分ですが、クラスの実装と設計のセマンティクスは重要な役割を果たします。