前の日 / 次の日 / 最新 / 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-09 Fri

リソース管理 [D言語]

デストラクタ

GC が参照されなくなったオブジェクトを必ず解放するという保証はありません。
さらに、
GC がデストラクタを呼び出す順番も保証されません。
これはつまり、
GC管理下にあるオブジェクトへの参照をメンバとして持つオブジェクトのデストラクタを
ガベージコレクタが呼び出すときには、それらの参照は既に無効となっている可能性があるということです。
従って、
デストラクタからはメンバオブジェクトを参照できません。
この規則は、
autoオブジェクトや DeleteExpression
で削除されるオブジェクト
(GCが自動で解放することはないので、参照は必ず有効)には当てはまりません。

GC でデストラクタが呼ばれる保証がない。
GC でデストラクタが呼ばれるのを、期待して、デストラクタにリソースの解放を書くと、
リソースリークする。

class ComString{...}
void main()
{
    ComString s = new ComString("foo"); //GC がデストラクタを呼ばないかもしれない。
}

GC で呼ばれるデストラクタからメンバオブジェクトを触れないので
scope属性や、delete式でデストラクタが実行されるようにしなければならない。

delete式では、忘れる可能性がある。

class ComString{...}
void main()
{
    ComString s = new ComString("foo"); //delete式を書き忘れた
}

scope変数を使いRAIIにしたい。
scope変数を使うように強制するためにscopeクラスする。

scope class ComString{...}
void main()
{
    scope ComString s = new ComString("foo"); //デストラクタが動く
}

scopeクラスにすると、
メンバオブジェクトにできない。

scope class ComString{...}
class MyString
{
    scope ComString s;//コンパイルエラー
    ComString s;//コンパイルエラー
}