는 ref
클래스 소멸자 Dispose pattern 통해 추상화이다. 컴파일
다음 C++/CLI 클래스, 다음 C# 코드에
public ref class Test
{
public:
Test() { System::Console::WriteLine("ctor"); }
~Test() { System::Console::WriteLine("dtor"); }
static void Foo()
{
auto foo = gcnew Test();
foo->~Test();
}
};
컴파일 해제 (그런 일이 무엇인지 시각화하는 좋은 방법이 그래서 C#을 의미가 기본이 IL 코드에 더 가까운) :
public class Test : IDisposable
{
public Test()
{
Console.WriteLine("ctor");
}
private void ~Test()
{
Console.WriteLine("dtor");
}
public static void Foo()
{
new Test().Dispose();
}
protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool A_0)
{
if (A_0)
{
this.~Test();
}
else
{
this.Finalize();
}
}
public virtual void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize((object)this);
}
}
처분 패턴이 컴파일러에 의해 자동으로 구현 된 것을 볼 수 있습니다.
~Test
"destructor"가 개인 메서드로 컴파일되고 IDisposable::Dispose
구현이 생성됩니다. 컴파일러는 또한 어떤 이유로 finalizer를 호출합니다.
또한 Foo
정적 메서드에서 볼 수 있듯이 foo->~Test();
은 Dispose
으로 호출됩니다. 컴파일러는 foo->Dispose();
에 직접 전화 할 수 없습니다.
그러나 표준 접근 방식은 "소멸자"(따라서 Dispose
방법을)를 호출하면 delete
키워드를 사용하는 것입니다 foo
가 관리 핸들 때 delete foo;
는 C++/CLI에서 foo->~Test();
과 동일합니다.
참고이 예에서, 쓰는 대신 :
auto foo = gcnew CppCli::Test();
foo->Whatever();
delete foo;
당신은 스택 의미를 사용할 수 및 쓰기 :
Test foo;
foo.Whatever();
foo.~Test();
이 foo
일반처럼, 범위를 벗어나면 호출됩니다 C++.
완전성을 위해 모든 것이 최종 자와 상호 작용하는 방법은 다음과 같습니다. 의 하나를 추가하자
public class Test : IDisposable
{
public Test()
{
Console.WriteLine("ctor");
}
// This is the real finalizer
~Test()
{
this.Dispose(false);
}
// This is what C++/CLI compiles ~Test to
// Let's call this MethodA
private void ~Test()
{
Console.WriteLine("dtor");
}
// This is what C++/CLI compiles !Test to
// Let's call this MethodB
private void !Test()
{
Console.WriteLine("finalizer");
}
[HandleProcessCorruptedStateExceptions]
protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool A_0)
{
if (A_0)
{
this.~Test(); // MethodA, NOT the finalizer
}
else
{
try
{
this.!Test(); // MethodB
}
finally
{
base.Finalize();
}
}
}
public virtual void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize((object)this);
}
}
주
는 C#에서 추가 혼란의 파이널 라이저는
~Test()
하다는 것을는
private void ~Test()
에서
다른입니다 : 이것은 다음과 같은 C#을 -like 코드로 컴파일 해제
public ref class Test
{
public:
Test() { System::Console::WriteLine("ctor"); }
~Test() { System::Console::WriteLine("dtor"); }
!Test() { System::Console::WriteLine("finalizer"); }
};
을 함수는 소멸자에 대해 C++/CLI 컴파일러가 생성합니다.
감사합니다. 자세한 설명을 주셔서 감사합니다. 정말 도움이됩니다. – Geek
'~ Test()'문법은 표준이 아님을 주목해야합니다. 관리 객체를 처리하는 표준 방법은 C++ 객체와 마찬가지로'delete'를 사용하는 것입니다. –
@DavidYaw, 맞아, 그게 중요한 포인트 야, 고마워! –