読者です 読者をやめる 読者になる 読者になる

ファイナライザ、デストラクタ

Java C# C++

読書会で話題に上がったけど、この辺の用語は言語によってまちまちで、かなり紛らわしい。
その場ではファイナライザとデストラクタは別物だよ、と言っただけなんで、補足を。


まずは、言語ごとに何を持っているのかの表を。

言語 ファイナライザ デストラクタ
Java あり なし
C# なし あり
C++ なし あり

ただし、C#のデストラクタはC++のデストラクタ*1より、Javaのファイナライザ*2と同じような意味を持つため、

言語 Javaでのファイナライザ相当品 C++でのデストラクタ相当品
Java あり なし*3
C# あり*4 あり*5
C++ なし あり

となる。
実際、C#でデストラクタを記述すると、以下のように記述したのと同じ意味となる。

protected override void Finalize()
{
    try
    {
        // デストラクタの中身
    }
    finally
    {
        base.Finalize();
    }
}

このように、C#ではデストラクタはファイナライザの実装の為のシンタックスシュガーでしかない。
しかし、C#にはIDisposableというインターフェイスがあり、これはまさにC++のデストラクタと同じような働き*6を持つ。


全く関係ない話題だけど、JavaC#は対象としている領域が似通っているから、この2つ共を扱うのはアリだと思う*7 *8
でも、C++は明らかに「混ぜるな危険」だと思うんだよなぁ。
抽象度をかなり上げていけばこれらは混ぜることも可能だと思うけど、果たしてそこまで抽象度を上げた話に言語が出てくるのかどうかが疑問だ。

*1:スコープを抜けた時、またはdeleteにより呼び出される

*2:GC時に呼び出される

*3:Closeableがその役割の一部を担っていると考えることは可能

*4:言語仕様上はデストラクタ

*5:IDisposableのDisposeメソッド

*6:スコープを抜けたら破棄される

*7:さすがにC#3.0とJavaSE6は限界があるかな、とは思うけど

*8:ジェネリクスを扱うなら、JavaC#C++も全部が全部違うんで、比較するくらいしかできないかも