1. ホーム
  2. c++

[解決済み] C++の私的継承はいつ使うべきですか?

2022-07-27 09:58:32

質問

C++の私的継承は、保護継承とは異なり、C++の開発の主流となりました。しかし、私はまだその良い使い方を発見していません。

皆さんはどんな時に使っていますか?

どのように解決するのですか?

回答受付後の注意事項 これは完全な答えではありません。次のような他の答えを読んでください。 ここで (概念的)および はこちら (理論的にも実践的にも)ご興味のある方はぜひご覧ください。これは、私的継承で実現できる派手なトリックに過ぎません。である一方 ファンシー の答えではありません。

C++のFAQ(他の人のコメントにリンクあり)に示されているプライベート継承だけの基本的な使い方の他に、プライベート継承と仮想継承の組み合わせで を封印します。 (.NET用語で) クラスを封印したり、クラスが 最終 (にすることができます(Java用語)。これは一般的な使い方ではありませんが、とにかく私はこれを面白いと思いました。

class ClassSealer {
private:
   friend class Sealed;
   ClassSealer() {}
};
class Sealed : private virtual ClassSealer
{ 
   // ...
};
class FailsToDerive : public Sealed
{
   // Cannot be instantiated
};

封印 はインスタンス化することができます。これは クラスシーラー を継承しており、フレンドであるためプライベートコンストラクタを直接呼び出すことができます。

フェイルトゥデライブ を呼び出さなければならないので、コンパイルできません。 クラスシーラ のコンストラクタを直接呼び出す必要があり(仮想継承の必要条件)、それが Sealed クラスではプライベートであり、この場合 FailsToDerive の友人ではありません。 ClassSealer .


EDIT

コメントで、当時は CRTP を使って汎用的に作ることができなかったと言及されています。C++11 標準では、テンプレート引数と仲良くするための別の構文を提供することで、その制限をなくしています。

template <typename T>
class Seal {
   friend T;          // not: friend class T!!!
   Seal() {}
};
class Sealed : private virtual Seal<Sealed> // ...

もちろん、これはすべて無意味なことで、C++11 では final コンテキスト キーワードが用意されているためです。

class Sealed final // ...