メモリプール(2)

先日のigaMemoryPoolクラスですが、実際にどのように使うのか書いて見ましょう。
現実的かどうかはともかく、こんなケースを考えてみましょう。

  • Bはリストをなす
  • AはBを管理する
  • MはAを持つが、直接Bを操作したい

そうすると、こんな感じでしょうか。


class B {

private:
B *next;
double x;

public:
B(double v){ x = v; }
inline void *operator new(size_t size, igaMemoryPool* mp)
{
return mp->alloc();
}
};

まず、class Bの定義です。引数つきnewの定義をしているところがポイントです。

class A {

private:
B *top;
igaMemoryPool *mp;

public:
A()
{
top = current = NULL;
mp = new igaMemoryPool(sizeof(B),1024);
}
~A(){ delete mp; }
inline igaMemoryPool *get_mp()
{
return mp;
}
};

続いてclass Aの定義です。メモリプールはここに持たせています。メモリプールにはBを格納します。メモリプールのアドレスを返すメソッドを用意しておきます。

class M {

private:
A *a;

public:
M(){ a = new A; }
void add(double x)
{
for (B *work = A->top; work != NULL; work = work->next){
if (work->x < x) break;
}

B *tmp_B = new (A->get_mp()) B(x);
tmp_B->next = work->next;
work->next = tmp_B;

if (A->top == NULL){
A->top = tmp_B;
}
}
};

最後にclass Mの定義です。
addメソッドではリストのノード(B)を追加します。引数つきのnewを使っています。そうするとメモリプールが返してくるアドレスのところにオブジェクトが配置されます。