type()を持たせてcastする

最近衝撃を受けた。
まず、typeを取得するだけのクラスを生成。

class Hoge
{
public:
  virtual int type() = 0;
};

ここでは、めんどくさいのでintにしてるけど、実際はstringやハッシュを。
それを継承したクラスを作る。

class A : public Hoge
{
public:
  static const int kType = 3;
  virtual int type() { return kType; }
  void AFunction() const ;
};
class B : public Hoge
{
public:
  static const int kType = 4;
  virtual int type() { return kType; }
  int BFunction() const;
};

A、BはHoge以外は全く別の機能。
Managerというようなクラスがあった時、こんなことができる。

void Manager::Function( const Hoge* hoge )
{
  if( hoge->type() == A::kType )
  {
     const A* cast_hoge = static_cast< const A* >( hoge );
     cast_hoge->AFunction(); //class Aの機能を呼び出す
  }
  else if( hoge->type() == B::kType )
  {
     const B* cast_hoge = static_cast< const B* >( hoge );
     cast_hoge->BFunction();  //class Bの機能を呼び出す
  }
}

type()で型を判断して、Hoge*をその型にcastしてしまう。
そしてHoge*にない、それぞれの独自機能を呼び出すことができる。
今までは、A、B共通の親クラスに機能を持たせたり、
ManagerにAを取る関数、Bを取る関数、
ということをしてきたけど、これはHogeとManagerのヘッダーを汚すことなくできる。