前の日 / 次の日 / 最新 / 2009-01

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

2009-01-23 Fri

デストラクタの中で呼び出し元を判別 [D言語]

たまたま、 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 を消してから、
デストラクタが呼ばれる。