memory pool

global operator new が、MALLOC()(システムメモリ)によって割り当てられている場合、あるクラスをメモリプールから割り当てるには、

class Hoge{
    void* operator new( size_t size ){
        return MemoryPool::malloc( size );
    }
    void operator delete( void* ptr ){
        return MemoryPool::free( ptr );
    }
    ...
};

こうする必要がある。
こうすれば、メモリプールからメモリが割り当てられ、

Hoge* hoge = new Hoge;

こうやって書いても null チェックをしなくてもいいようになる。


しかし、自分の場合、会社のライブラリがメモリプールから割り当てられていなくて、しかもそのライブラリを書き換えてはいけない。つまり、Hoge クラスを触ってはならない。
どうしようかと悩んだ末、次のようにした。

class global_memory_pool{
    void* operator new( size_t size ){
        return MemoryPool::malloc( size );
    }
    void operator delete( void* ptr ){
        return MemoryPool::free( ptr );
    }
};

class HogeEx : public Hoge , public global_memory_pool{
    // 中身はいらない
};

こうすれば、HogeEx は Hoge と全く同じ扱いが出来るようになって、しかもメモリプールから確保されるようになる。
ただし、

Hoge* hoge = new HogeEx();
delete hoge;

とかやってしまうと、Hoge のデストラクタが呼ばれてしまう。めちゃめちゃ危険。


これは生で扱うことは絶対にせずに、スマートポインタと併用しましょう。。

smart_ptr< Hoge > hoge( new HogeEx );

これで、null チェック不必要の、解放を気にしなくていい自前のライブラリラッパの出来上がりですヽ(´ー`)ノ


追記:
int 型とかの基本型は、次のようにします。

class Integer : public global_memory_pool{
public:
    Integer() : _value( 0 ){}
    operator int&(){ return _value; }
private:
    int _value;
};

これで、コンストラクタで 0 に初期化される以外は全く同じ動作をします。


追記2:
ちゅーかこれ、天ぷらにしてやればええんじゃないでしょか。

template< class T , class M = global_memory_pool >
class Memory : public T , public M{};
smart_ptr< Hoge > hoge( new Memory< Hoge > );

テラウマス(*´ω`)