関数 - c++ 継承 protected アクセスできない




効果的なC++:保護された継承を阻止するか? (4)

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(); }
};

Scott MeyersのEffective C ++ (第3版)とItem 32のパラグラフを読んでいました。 パブリック継承が 151ページの「is-a」であることを確認します(私は太字で示しています)。

これは公開継承の場合にのみ当てはまります。 StudentがPersonから公に派生した場合にのみ記述されているように、C ++は動作します。 私的継承とはまったく異なるものを意味します(アイテム39参照)。 保護された継承は、今日まで私に意味が分かりません。

質問 :このコメントをどのように解釈すべきですか? マイヤーズは、保護された遺産を伝えることはめったに役に立たず、避けるべきですか?

(私はプライベートとパブリックとプロテクト継承の違いC ++ FAQ Liteのプライベートと保護された継承セクションの 違いを知りました。どちらもプロテクション継承の意味について説明していますが、いつ、どのように有用だろう。)


うん、保護された継承または私的継承の用途はあまりない。 あなたが個人的な継承について考えているなら、チャンスはあなたに適しています。 (継承は「is-a」を意味し、構成の意味は「a-a」です。)

私の推測では、C ++委員会がこれを簡単に追加したのは、それが非常に簡単であったため、「誰かがこれをうまく利用することができるかもしれない。 それは悪い特徴ではない、それは誰もそれのための実際の使用をまだ見つけていないということだけで、どんな害もしない。 :P


保護が必要なシナリオ:

  1. あなたは、外にその機能を公開したくないということを知っているメソッドを持つ基本クラスを持っていますが、派生クラスには便利だとわかっています。

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

複数の継承のおかげで、基底クラスの継承型で遊んで、既存のロジックと実装でより多様なクラスを構築できます。

より具体的な例:

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

Observer
Subject
Factory

今では、これらのすべてを公開したいと思っています。なぜなら、一般的に、あなたは何でもパターンを使うことができるからです。

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

もう一つの例:

たとえば、ライブラリクラスを継承したいとします(私はそれを推奨しません)。 あなたはあなたがstd::list<>または "better" shared_ptrのクールな拡張をしたいとします。

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

あなたはおそらくカプセル化を代わりに使うことができますが、継承はIS Aの適切なロジックに従います(またはこの場合はAの種類です)


彼は保護された継承を厳密に落胆させているわけではありません。 私は他の誰かを見たことがない。

本当に便利なユースケースが2つ見つかった場合は、書籍を書くための資料があるかもしれません。 :-)





effective-c++