継承できないクラス

こんにちは、株式会社CFlatです。

C++11ではfinalキーワードが導入され、継承できないクラスを作ることが容易になりました。
例えば次のようなHogeクラスを継承しようとすると、エラーが発生します。

class Hoge final {};

クラス自体は継承可能だけれども、メンバー関数のみ継承不能とすることもできます。

class Piyo
{
public:
  virtual void method() final {}
};

ただしC++03の範囲でも、工夫すれば継承不能なクラスを作ることはできなくはありませんでした……つまり、デフォルトコンストラクタを含めて全てのコンストラクタをprivateとすることで、派生クラスが基底クラスを構築できないようにするわけです(派生クラスの宣言だけなら通っても、インスタンス化する時にエラーとなります)。
もちろん、そのままでは継承せずに使うこともできなくなりますので、インスタンス生成用のstaticメンバー関数などを用意することになります。

class Hoge03
{
private:
  Hoge03() {}
  Hoge03(const Hoge03&) {}

public:
  static Hoge03 *create() { return new Hoge03(); }
};

余談……むしろ本題

あるクラスの子孫クラスは、特定のクラスのうちいずれかでなければならない(ライブラリ内で親クラス→子クラスの継承はするが、それ以外親クラスも子クラスも継承することはできない)、というライブラリを想定します。
上記の2つの方法を組み合わせて、さらにfriendを使えばこの通り。

class Base
{
  friend class Derived1;
  friend class Derived2;

private :
  Base() {}
  Base(const Base&) {}
};

class Derived1 final : public Base {};
class Derived2 final : public Base {};
// class Derived3 : public Base {} d; // ERROR!
// class Derived4 : public Derived1 {}; // ERROR!