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); } }