私自身の(たとえば、conatiner)テンプレートクラスのトレイトクラステンプレートから継承することの短所は何ですか?それは慣習的で合法ですか?
3 に答える
*_traits
いくつかの面でのみ異なる必要がある場合、トレイトのみが他のトレイト(C ++標準ライブラリが呼び出すものの厳密な意味で)を継承できます。ただし、メンバーの定義を簡素化する、継承を目的とした他の同様のクラスがあります。たとえば、イテレータstd::iterator
を定義する場合、適切なタグtypedefを定義するために継承する可能性があります。
通常、traitsクラスは単なるtypedefの集まりです。それらをすべてクラスに入れたい場合は、それらから継承できます。通常、それらには(非静的)メンバーがないため、実際には空のクラスであり、それらから継承すると、空の基本クラスの最適化が適用されます。だから、短所は何である可能性があります:
- 継承は通常、is-a関係を意味します。OO-したがって、純粋主義者は、純粋な技術的理由のためにそれを使用すべきではないと言うかもしれません。しかし、C ++では、純粋な技術的継承が頻繁に使用されるため、気にしません。
- 複数の基本クラスがある場合、一部のコンパイラはEBCOを適用しなくなります。そのため、継承するトレイト基本クラスオブジェクトは、データが含まれていなくても、クラスオブジェクトの一部のスペースを占有します。
相続、EBCOなどに関するその他の資料:
状況によります。継承のオブジェクト指向の概念と、派生のC++実装手法を区別します。
(この語彙の選択は個人的なものです。区別されることはあまりありませんが、私見では、設計コンセプトと実装手法を区別することが重要です。)この場合、特性から継承しないと言えます。isA関係がないため、クラス。一方、継承は通常、継承を実装するために使用されますが、可能な使用法はそれだけではありません。この派生がそうではないstd::iterator
ことが明らかである限り、特性クラスから派生することは完全に正常です(たとえば、ほとんどのイテレータが派生する方法で)オブジェクト指向の意味で、継承を実装するために使用されます。特に、へのポインタを介してイテレータを操作する人を望まないでしょう
std::iterator
。
特性クラスは、それらを介した削除のリスクを防ぐために、デストラクタを保護していることが(少なくともハーブサッターによって)示唆されています。私は完全に確信しているわけではありません。トレイトクラスのセマンティクスは、通常、ポインタを作成することさえ誰にも起こらないようなものです。(コードで最後に見たのstd::iterator*
はいつですか?)(一方、質問されるかもしれません:なぜですか?保護されたデストラクタは、トレイトクラスがPODではないことを意味しますが、合理的なことは考えられませんこれが重要な場合。)
とにかく、いくつかを取得するためにトレイトクラスから公に継承することtypedef
は、標準のC++イディオムです。