【C++】Type Erasure

2018年10月24日

オブジェクトの型情報を消去し、あらゆる型を扱うためのイディオム( 基底クラスとテンプレート派生クラスを用いる方法 )。

実装方法

まず、インターフェースとなる基底クラスを定義する。

class Base 
{
public:
    Base()          = default;
    virtual ~Base() = default;

    virtual void Output() = 0;
};

そして、そのクラスを継承して、テンプレート派生クラスを作る。

これで基底クラスを介して、派生クラスのテンプレートの型情報を隠蔽できる。

template<class T>
class Derived : public Base 
{
public:
    Derived( T value ) : 
        value( value )
    {
    }

    virtual ~Derived() = default;

    virtual void Output() override 
    {
        std::cout << this->value << std::endl;
    }
private:
    T value;
};

あとは使用時に派生クラスを見せないようにするため、そのラッパーとなるクラスを作成する。

class Wrapper
{
public:
    template<class T>
    Wrapper( T value ) :
        pBase( std::make_unique<Derived<T>>( value ) )
    {
    }

    void Output() 
    {
        this->pBase->Output();
    }
private:
    std::unique_ptr<Base> pBase;
};

使い方

ラッパーのクラスをインスタンス化して、使用する。

Wrapper wrapper( 100 );
wrapper.Output();

参考書籍