質問

C ++では、基本クラスからプライベート/保護を継承したい場合は考えられません。

class Base;
class Derived1 : private Base;
class Derived2 : protected Base;

本当に役に立つのでしょうか?

役に立ちましたか?

解決

これは、基本クラスの一部のメンバーにアクセスしたいが、クラス インターフェイスで公開せずにアクセスしたい場合に便利です。プライベート継承は、ある種の構成とみなすこともできます。の C++ FAQ ライト このステートメントを説明するために次の例を示します

class Engine {
 public:
   Engine(int numCylinders);
   void start();                 // Starts this Engine
};

class Car {
  public:
    Car() : e_(8) { }             // Initializes this Car with 8 cylinders
    void start() { e_.start(); }  // Start this Car by starting its Engine
  private:
    Engine e_;                    // Car has-a Engine
};

同じセマンティクスを取得するには、次のように car Class を記述することもできます。

class Car : private Engine {    // Car has-a Engine
 public:
   Car() : Engine(8) { }         // Initializes this Car with 8 cylinders
   using Engine::start;          // Start this Car by starting its Engine
}; 

ただし、この方法にはいくつかの欠点があります。

  • あなたの意図ははるかに明確ではありません
  • 不正な多重継承につながる可能性があります
  • Engine クラスの保護されたメンバーにアクセスできるため、Engine クラスのカプセル化が解除されます。
  • Engine の仮想メソッドをオーバーライドすることができますが、目的が単純な構成の場合は望ましくないことです。

他のヒント

プライベートはかなりの数の状況において有用であることができます。ただ、そのうちの一つは、ポリシーがあります:

は、部分的なクラステンプレートの特殊化ですこの設計上の問題への答えですかます。

それが有用である別の機会は、コピーと割り当てを禁止することである。

struct noncopyable {
    private:
    noncopyable(noncopyable const&);
    noncopyable & operator=(noncopyable const&);
};

class my_noncopyable_type : noncopyable {
    // ...
};
我々は、ユーザーが私たちのオブジェクトに型noncopyable*のポインタを持っていることを望んでいないので、

、我々は個人的に導き出します。それはあまりにもだけでなく、コピー不可のため、他の多くのこのようなクラス(最も一般的政策)をカウントします。

公共継承モデルIS-A。
非パブリック継承モデル - 実装されている-IN-TERMS-OF。
封じ込めモデルは、IS-IMPLEMENTED-IN-TERMS-OFに相当し、-Aを持っています。

サッタートピックの上。あなたは実装の詳細については、封じ込めの上に非パブリック継承を選択したいとき、彼は説明しています。

たとえば、あなたが実装を再利用ではなく、クラスのインタフェースとその仮想関数をオーバーライドしたいときます。

private継承は主に間違った理由のために使用されています。以前の回答で示されているように人々は、IS-IMPLEMENTED-IN-TERMS-OFにそれを使用しますが、私の経験では、それはコピーを保持ではなくクラスから継承するためにいつもよりきれいです。もう以前の答え、CBigArrayについての一つは、このアンチパターンの完璧な例を提供しています。

私が持っている-aが原因「保護」のオーバー熱心な使用には動作しませんが、新しいクラスを分割するよりも、それが壊れたクラスを修正する方が良いでしょうとき例があるかもしれないことを実現します。

私は1つのポイントまたは他の両方のプライベートと保護継承を使用しました。

プライベート継承を使用すると、基本クラスの振る舞いを持っている何かをしたいときに便利ですし、その機能を無効にすることはできますが、あなたは全世界がそれを認識し、それを使用する必要はありません。あなたはまだそのインターフェイス関数の戻りを持つことにより、個人派生クラスのインタフェースを使用することができます。あなたは物事は、彼らがプライベートインターフェイスを使用して自分自身を登録することができますようコールバックを待機するために自分自身を登録することができたときにも便利です。

あなたが別のクラスからの便利な機能を引き出す基本クラスを持っていますが、唯一その派生クラスは、それを使用することができるようにしたいとき

保護継承が特に便利です。

私はかつてこれらのデータ構造をクラスとして実装しました。

  • リンクされたリスト
  • 汎用配列 (抽象)
  • 単純な配列 (汎用配列から継承)
  • 大きな配列 (汎用配列から継承)

大きな配列のインターフェイスでは配列のように見えますが、実際には固定サイズの単純な配列のリンク リストでした。そこで私は次のように宣言しました。

template <typename T>
class CBigArray : public IArray, private CLnkList {
    // ...
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top