67

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

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

本当に便利ですか?

4

8 に答える 8

54

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

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 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仮想メソッドをオーバーライドすることが許可されています。これは、目的が単純な構成である場合は望ましくありません。
于 2008-12-17T12:40:08.810 に答える
40

プライベートは、かなりの数の状況で役立ちます。それらの1つだけがポリシーです。

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

コピーと割り当てを禁止することが役立つもう1つの機会は次のとおりです。

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

class my_noncopyable_type : noncopyable {
    // ...
};

ユーザーがオブジェクトへの型のポインターを持っていることを望まないのでnoncopyable*、私たちは個人的に派生します。これは、コピーできないクラスだけでなく、他の多くのそのようなクラスにも当てはまります(ポリシーが最も一般的です)。

于 2008-12-17T12:36:30.067 に答える
16

公開継承モデル IS-A.
非パブリック継承モデルは IS-IMPLEMENTED-IN-TERMS-OF です。
封じ込めモデル HAS-A。これは IS-IMPLEMENTED-IN-TERMS-OF と同等です。

話題のサッター。彼は、実装の詳細について、コンテインメントよりも非公開の継承を選択する場合について説明しています。

于 2008-12-17T14:21:14.300 に答える
3

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

于 2008-12-17T16:01:34.380 に答える
1

ある時点で、プライベート継承と保護継承の両方を使用しました。

プライベート継承は、何かに基本クラスの動作を持たせ、その機能をオーバーライドできるようにしたいが、全世界にそれを認識させて使用させたくない場合に便利です。関数がそのインターフェイスを返すようにすることで、プライベートに派生したクラスのインターフェイスを引き続き使用できます。また、プライベート インターフェイスを使用して自分自身を登録できるため、コールバックをリッスンするために自分自身を登録できる場合にも役立ちます。

保護された継承は、別のクラスから有用な機能を派生させる基本クラスがあり、その派生クラスだけがそれを使用できるようにしたい場合に特に便利です。

于 2008-12-17T16:03:51.630 に答える
0

プライベート継承は、is-a によって関連付けられていない 2 つのクラスを扱っている場合に、正当な設計戦略である可能性が最も高く、一方が他方の保護されたメンバーにアクセスする必要があるか、1 つ以上の仮想関数を再定義する必要があります。

191 の Scott Meyers の効果的な C++ 第 3 版ページから。

于 2022-01-22T03:15:29.983 に答える
-1

これらのデータ構造をクラスとして実装したことがあります。

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

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

template <typename T>
class CBigArray : public IArray, private CLnkList {
    // ...
于 2008-12-17T16:08:19.217 に答える