C++地獄へようこそ。
C ++の最も物議を醸す側面の1つに触れたばかりです。std::stringはポリモーフィックではなく、コンストラクターは継承されません。
唯一の「クリーンな」方法(これはいかなる種類の批判もしません)は、std :: stringをメンバーとして埋め込み、そのすべてのメソッドを委任することです。よくできました!
他の方法も考えられますが、常にいくつかの制限に注意する必要があります。
- std :: stringには仮想メソッドがないため、それを派生させても、ポリモーフィック型は取得されません。
- つまり、yoyがWordを刺し傷保持関数に渡し、その関数が文字列メソッドを呼び出す場合、オーバーライドメソッドは呼び出されず、
- Word viaの割り当てを
new
文字列に指定してはなりません*:そのようなポインタを介して削除すると、未定義の動作が発生します
- stringを受け取りstring-sを返す継承されたメソッドはすべて機能しますが、Wordではなくstringを返します。
コンストラクターについては、継承されません。デフォルトの構造継承は幻想です。これは、コンパイラがデフォルトのデフォルト実装を合成し、コピーして割り当て、暗黙的にベースを呼び出すためです。
C ++ 11では、回避策は次のようになります。
class Word: public std::string
{
public:
template<class... Args>
Word(Args&&... args) :std::string(std::forward<Args>(args)...)
{}
//whatever else
};
これにより、適切なstd :: sting ctorの呼び出しで指定されるあらゆる種類の引数が作成されます(存在する場合は、コンパイルエラーが発生します)。
次に、デザインを自分で決定します。通常のstd::stringと独立した無料関数のセットが付属している可能性があります。
別の(不完全な)方法は、Wordを継承せずに、std :: stringを埋め込み、上記のように構築し、暗黙的にstd::stringに変換できるようにすることです。(さらに、str()明示的なメソッドがあります)。これにより、Wordを文字列として使用したり、文字列からWordを作成したりできますが、文字列の「代わりに」Wordを使用することはできません。
学ぶべきもう1つのこと(Javaからの可能性があります...):「is-a=継承およびhas-a=埋め込み」OOPルールに自分自身を固定しないでください。すべてのC++標準ライブラリオブジェクトはOOPの意味でのオブジェクトではないため、すべてのOOPスクールの方法論にはその文脈での誤謬があります。
単純なコーディング(および「自分自身を繰り返さない」パラダイムの適切な適用、継承によりはるかに簡単)と単純なメンテナンス(および埋め込みによりコードが使用されにくくなる)の間のトレードオフを決定する必要があります。他人によって間違って)
これは、以下のコメントに対する回答です。
「標準のC++クラスのポリモーフィズムの欠如。これはなぜですか?仮想関数を使用してstd C ++ libsを実装しないことは、それらが強化するように設計された言語のポイントを打ち負かしているようです!!!「」
ええと...はい、そうではありません!
PERLを引用しているので、次のことを考慮してください。PERLはスクリプト言語であり、型は動的です。-Javaは、型が静的でオブジェクトが動的である言語です-C ++は、型が静的でオブジェクトが静的である言語です(オブジェクトの動的割り当ては明示的です)。
現在、Javaでは、オブジェクトは常に動的に割り当てられ、ローカル変数はそれらのオブジェクトへの「参照」です。C ++では、ローカル変数はそれ自体がオブジェクトであり、値のセマンティクスを持っています。また、C ++標準ライブラリは、拡張するベースのセットとしてではなく、テンプレートを使用してコードを生成する値型のセットとして設計されています。
std::string
は、動作と同じように機能するものと考えてint
ください。intから派生して、「より多くのメソッド」を取得したり、一部のメソッドの動作を変更したりすることを期待していますか?
ここでの論争の的となる側面は、-この設計と一貫性を保つために-std :: stringはその内部メモリを管理するだけで、メソッドを持たないようにする必要があるということです。代わりに、文字列関数sholdはテンプレートとして実装されているため、同じstd::string外部動作を示す他のクラスで「アルゴリズム」として使用できます。デザイナーがしなかったこと。
彼らはそれに多くのメソッドを配置しましたが、値のセマンティクスを保持することを多形にしないため、設計があいまいになり、それらのメソッドを再宣言せずに「再利用」する唯一の方法を継承に保持します。これは可能ですが、私があなたに言った制限があります。
新しい機能を効果的に作成したい場合、「価値のポリモーフィズム」を持たせるには、teplatesを使用します。
std::string capitalize(const std::string& s) { .... }
次のようなことをします
template<class String>
String capitalize(const String& s) { .... }
これにより、どのタイプの文字でも、文字に関して同じ文字列インターフェイスを持つクラスをコーディングできます。