22

私はScottMeyersのEffectiveC++(第3版)を読んでいて、項目32の段落で:パブリック継承が151ページの「is-a」であることを確認してください。

これは、パブリック継承にのみ当てはまります。C ++は、StudentがPersonから公に派生している場合にのみ、私が説明したように動作します。プライベート継承とはまったく異なるものを意味し(項目39を参照)、保護された継承とは、今日までその意味が理解できないものです。

質問:このコメントをどのように解釈すればよいですか?マイヤーズは、保護された継承が有用であるとはめったに考えられず、避けるべきであることを伝えようとしていますか?

(私は 、プライベート、パブリック、および保護された継承の違いとC ++ FAQ Liteのプライベートおよび保護された継承のセクションを読みました。どちらも保護された継承の意味を説明していますが、いつ、なぜそれが行われるのかについてはあまり洞察がありません。役に立つでしょう。)

4

5 に答える 5

10

保護が必要ないくつかのシナリオ:

  1. 機能を外部に公開したくないことがわかっているメソッドを含む基本クラスがありますが、派生クラスには役立つことがわかっています。

  2. そのクラスを拡張する任意のクラスによって論理的に使用されるべきであるが、決して外部に公開されるべきではないメンバーを持つ基本クラスがあります。

多重継承のおかげで、基本クラスの継承タイプをいじって、既存のロジックと実装でより多様なクラスを構築できます。

より具体的な例:

デザイン パターン ロジックに従ういくつかの抽象クラスを作成できます。

Observer
Subject
Factory

一般に、パターンは何にでも使用できるため、これらをすべて公開する必要があります。

ただし、保護された継承では、オブザーバーとサブジェクトであるクラスを作成できますが、保護されたファクトリのみであるため、ファクトリ部分は継承されたクラスでのみ使用されます。(例としてランダムなパターンを選択しただけです)

もう一つの例:

たとえば、ライブラリ クラスから継承したいとします (私はそれをお勧めしません)。std::list<>独自のクールな拡張機能または「より優れた」を作成したいとしましょうshared_ptr

基本クラス (パブリック メソッドを持つように設計されています) から保護された形で派生できます。
これにより、独自のカスタム メソッドを使用したり、クラスのロジックを使用したり、そのロジックを任意の派生クラスに渡すことができます。

代わりにカプセル化を使用することもできますが、継承はIS Aの適切なロジックに従います (または、この場合は IS のようなものです)。

于 2011-06-26T13:49:56.567 に答える
5

彼は保護された継承をまったく思いとどまらせているわけではありません。私は他の場所でも誰も見たことがありません。

本当に役立つユースケースをいくつか見つけた場合は、本を書くための資料もあるかもしれません。:-)

于 2011-06-26T13:58:02.337 に答える
3

はいといいえ。私自身、保護された継承も悪い機能だと思います。基本的に、基本クラスのすべてのパブリック メンバーとプロテクト メンバーをプロテクト メンバーとしてインポートします。

私は通常、保護されたメンバーを避けますが、リンク時の最適化が不十分なコンパイラで極端な効率を必要とする最低レベルでは、それらは役立ちます。しかし、それに基づいて構築されたものはすべて、元の基本クラスの (データ) メンバーをいじってはならず、代わりにインターフェイスを使用してください。

Scott Meyer が言おうとしていると思うのは、問題を解決する場合は保護された継承を引き続き使用できるということですが、意味的に明確ではないため、継承を説明するために必ずコメントを使用してください。

于 2011-06-26T13:53:54.177 に答える
3

はい、保護された継承またはプライベート継承の用途はあまりありません。プライベート継承について考えたことがある場合は、コンポジションの方が適している可能性があります。(継承は「ある」を意味し、合成は「ある」を意味します。)

私の推測では、C++ 委員会は単純にこれを追加したのです。なぜなら、これは非常に簡単に実行でき、「誰かがこれの適切な使用方法を見つけるだろう」と考えたからです。これは悪い機能ではなく、何の害もありませんが、まだ実際に使用されている人はいません。:P

于 2011-06-26T14:08:00.580 に答える
2

Meyers が保護された継承の使用を控えるようにアドバイスしているかどうかはわかりませんが、Meyers がチームにいる場合は避けるべきです。少なくとも彼はあなたのコードを理解できないからです。

あなたの同僚が彼よりも C++ をよく知っているのでない限り、保護された継承から離れるべきでしょう。誰もが別の方法、つまり構成を使用することを理解するでしょう。

ただし、それが理にかなっているケースを想像できます。コードを変更できないクラスの保護されたメンバーにアクセスする必要がありますが、IS-A 関係を公開したくない場合です。

class A {
protected:
  void f(); // <- I want to use this from B!
};

class B : protected A {
private:
  void g() { f(); }
};

その場合でも、パブリックメソッドで保護された基本メンバーを公開するパブリック継承を使用してラッパーを作成し、これらのラッパーで構成することを検討します。

/*! Careful: exposes A::f, which wasn't meant to be public by its authors */
class AWithF: public A {
public:
  void f() { A::f(); }
};

class B {
private:
  AWithF m_a;
  void g() { m_a.f(); }
};
于 2011-06-27T15:57:15.580 に答える