{{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;
}