C ++では、基本クラスからプライベート/保護を継承したい場合は考えられません。
class Base;
class Derived1 : private Base;
class Derived2 : protected Base;
本当に便利ですか?
C ++では、基本クラスからプライベート/保護を継承したい場合は考えられません。
class Base;
class Derived1 : private Base;
class Derived2 : protected Base;
本当に便利ですか?
基本クラスの一部のメンバーにアクセスしたいが、クラスインターフェイスでそれらを公開しない場合に便利です。プライベート継承は、ある種の構成と見なすこともできます。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
};
ただし、この方法にはいくつかの欠点があります。
プライベートは、かなりの数の状況で役立ちます。それらの1つだけがポリシーです。
部分的なクラステンプレートの特殊化は、この設計上の問題に対する答えですか?。
コピーと割り当てを禁止することが役立つもう1つの機会は次のとおりです。
struct noncopyable {
private:
noncopyable(noncopyable const&);
noncopyable & operator=(noncopyable const&);
};
class my_noncopyable_type : noncopyable {
// ...
};
ユーザーがオブジェクトへの型のポインターを持っていることを望まないのでnoncopyable*
、私たちは個人的に派生します。これは、コピーできないクラスだけでなく、他の多くのそのようなクラスにも当てはまります(ポリシーが最も一般的です)。
公開継承モデル IS-A.
非パブリック継承モデルは IS-IMPLEMENTED-IN-TERMS-OF です。
封じ込めモデル HAS-A。これは IS-IMPLEMENTED-IN-TERMS-OF と同等です。
話題のサッター。彼は、実装の詳細について、コンテインメントよりも非公開の継承を選択する場合について説明しています。
たとえば、実装を再利用したいが、クラスのインターフェースを再利用したくない場合や、その仮想関数をオーバーライドしたい場合などです。
ある時点で、プライベート継承と保護継承の両方を使用しました。
プライベート継承は、何かに基本クラスの動作を持たせ、その機能をオーバーライドできるようにしたいが、全世界にそれを認識させて使用させたくない場合に便利です。関数がそのインターフェイスを返すようにすることで、プライベートに派生したクラスのインターフェイスを引き続き使用できます。また、プライベート インターフェイスを使用して自分自身を登録できるため、コールバックをリッスンするために自分自身を登録できる場合にも役立ちます。
保護された継承は、別のクラスから有用な機能を派生させる基本クラスがあり、その派生クラスだけがそれを使用できるようにしたい場合に特に便利です。
プライベート継承は、is-a によって関連付けられていない 2 つのクラスを扱っている場合に、正当な設計戦略である可能性が最も高く、一方が他方の保護されたメンバーにアクセスする必要があるか、1 つ以上の仮想関数を再定義する必要があります。
191 の Scott Meyers の効果的な C++ 第 3 版ページから。
これらのデータ構造をクラスとして実装したことがあります。
大きな配列のインターフェイスは配列のように見えますが、実際には固定サイズの単純な配列のリンクされたリストでした。だから私はそれを次のように宣言しました:
template <typename T>
class CBigArray : public IArray, private CLnkList {
// ...