プライベートな継承が必要なケースはまれに見ましたが、保護された継承が必要なケースに遭遇したことはありません。誰かに例がありますか?
3 に答える
ここの人々は、Protected クラスの継承と Protected メソッドを誤解しているようです。
FWIW、保護されたクラスの継承を使用している人を見たことがありません。私の記憶が正しければ、Stroustrup は「保護された」レベルを C++ の間違いと見なしていたと思います。その保護レベルを削除し、パブリックとプライベートのみに依存する場合、できないことはほとんどありません。
保護された継承の使用例は非常にまれです。共分散を利用したい場所です:
struct base {
virtual ~base() {}
virtual base & getBase() = 0;
};
struct d1 : private /* protected */ base {
virtual base & getBase() {
return this;
}
};
struct d2 : private /* protected */ d1 {
virtual d1 & getBase () {
return this;
}
};
前のスニペットは、「getBase」関数を提供することにより、何らかの理由で、基底クラスを非表示にし、基底とその関数の制御された可視性を提供しようとしました。
ただし、が から派生したものであることが分からないため、 structd2
では失敗します。したがって、動作しません。これを回避する方法は、継承が d2 で表示されるように、保護されたものを派生させることです。d2
d1
base
covariance
これを使用する同様の例は、 から派生するがstd::ostream
、ランダムな人がストリームに書き込むことを望まない場合です。を返す仮想getStream
関数を提供できますstd::ostream&
。その関数は、次の操作のためにストリームの準備を行うことができます。たとえば、特定のマニピュレータを配置します。
std::ostream& d2::getStream() {
this->width(10);
return *this;
}
logger.getStream() << "we are padded";
C++ FAQ Liteは、プライベート継承を使用することが正当な解決策である場合について言及しています ( [24.3.] 合成とプライベート継承のどちらを優先すべきか? を参照してください)。仮想関数 (この場合はderivedFunction()
)を介してプライベート基本クラス内から派生クラスを呼び出したい場合です。
class SomeImplementationClass
{
protected:
void service() {
derivedFunction();
}
virtual void derivedFunction() = 0;
// virtual destructor etc
};
class Derived : private SomeImplementationClass
{
void someFunction() {
service();
}
virtual void derivedFunction() {
// ...
}
// ...
};
Derived クラスから派生させBase::service()
、派生クラス内から使用したい場合 (たとえば、派生クラスに移動Derived::someFunction()
したい場合)、これを実現する最も簡単な方法は、プライベート継承Base
を保護継承に変更することです。
申し訳ありませんが、より具体的な例を考えることはできません。個人的には、「継承関係を保護するか非公開にするか」という議論で時間を無駄にしないように、すべての継承を公開するのが好きです。