2009-01-23
たまたま、 BlkAttr.FINALIZE のクリアのタイミングが違うから、
dmd 2.023 で出来たけど…
class C { ~this() { writefln(GC.getAttr(cast(void*)this)&GC.BlkAttr.FINALIZE); } } void main() { C c1 = new C; delete c1; { scope C c2 = new C; } C c3 = new C; writefln("---"); }
1 0 --- 0
delete で呼び出されたデストラクタ中では、 BlkAttr.FINALIZE が立っている。
GC で呼び出されたデストラクタ中では、 BlkAttr.FINALIZE が立っていない。
デストラクタの中で呼び出し元が判別できる。
よって次のコードが書ける。
class C { ~this() { if(GC.getAttr(cast(void*)this)&GC.BlkAttr.FINALIZE) { writefln("Clean up all managed resources"); } writefln("Clean up all native resources"); } }
scope 変数の場合 GC から呼ばれた場合と同じく BlkAttr.FINALIZE を消してから、
デストラクタが呼ばれる。