GCヒープ外へのクラスオブジェクトの作成
Dのクラスオブジェクトは、通常、ガベージコレクタ(GC)ヒープに配置されます。 場合によっては、C実行時ライブラリのヒープなど、 外部のヒープにインスタンスを作りたいこともあります。 これを実現するスタンダードな方法は、クラスのnew演算子とdelete演算子を オーバーロードすることです。それができない場合には、 以下の方法があります。このテクニックは、Dの動作する"縁の下"に関わってくるため、 全てのDコンパイラで動作することは保証できません。 特に、コンストラクタとデストラクタの呼び出し方は、 移植性がありません。
以下のモジュールが、まさにその処理を実現しています:
import std.c.stdlib;
import std.outofmemory;
// これは D 実行時ライブラリの一部
extern (C) void _d_callfinalizer(void *p);
class Foo
{
this(int x, char c) { ... }
~this() { ... }
}
Foo alloc_Foo(int x, char c)
{
ClassInfo ci = Foo.classinfo;
Foo f;
void *p;
p = std.c.stdlib.malloc(ci.init.length);
if (!p)
std.outofmemory._d_OutOfMemory();
// 初期化
(cast(byte*)p)[0 .. ci.init.length] = ci.init[];
f = cast(Foo)p;
// コンストラクタを実行
f._ctor(x, c);
return f;
}
void free_Foo(Foo f)
{ void* p = cast(void*)f;
if (p)
{
_d_callfinalizer(p); // デストラクタ呼び出し
std.c.stdlib.free(p);
}
}
