{{indexmenu_n>35}} ====== IDisposableとdeleteその2 ====== ・途中です IDisposableの実装はDisposeパターンが推奨されていて、C++/CLIでデストラクタ、ファイナライザを書くとこのパターンにのっとってコードが生成されます。 デストラクタ~A()とファイナライザ!A()はそのまま定義され、それらをコールする、Disposeメソッド、Finalizeメソッドが定義されます。以下、実際のC++/CLIがどのようにコンパイルされるかを調べます。 ref class A { public: ~A() { System::Console::WriteLine("~A()"); } }; ref class B : A{ ~B() { System::Console::WriteLine("~B()"); } }; void testfunc() { A^ a = gcnew A; B^ b = gcnew B; delete a; delete b; } int main() { testfunc(); return 0; } このコードをコンパイルし、[[http://www.red-gate.com/products/reflector/|.NET Reflector]]を使ってC#のコードを見ると以下のようになってます。 internal class A : IDisposable { // Methods private void ~A() { Console.WriteLine("~A()"); } public sealed override void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1) { if (flag1) { this.~A(); } else { base.Finalize(); } } } internal class B : A { // Methods private void ~B() { Console.WriteLine("~B()"); } protected override void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1) { if (flag1) { try { this.~B(); } finally { base.Dispose(true); } } else { base.Dispose(false); } } } internal static void modopt(CallConvCdecl) testfunc() { B b = null; A a = null; a = new A(); b = new B(); IDisposable disposable2 = a; if (disposable2 != null) { disposable2.Dispose(); } IDisposable disposable = b; if (disposable != null) { disposable.Dispose(); } } internal static int modopt(CallConvCdecl) main() { testfunc(); return 0; }