.NET ソフトウェア フレームワークに基づく Microsoft テクノロジ。 特定のカテゴリに適合しないその他のトピック。
C++/CLIではIDisposableは暗黙的に実装されるので明示的な実装はできません。(C#/VBなどからはその暗黙的に実装されたDispose()を実行できる)
重要 .NET Framework では、C++ コンパイラはリソースの確定的な破棄をサポートしており、 Dispose メソッドを直接実装することはできません。
C++では言語の仕様として削除の機能がある兼ね合いで、このようになっているらしいです。
IDisposable インターフェイスで言語をC++にするとC++/CLIでの扱い方の説明があります。
表示が気に入らないだけなら#defineで偽装すればいいです
#define Dispose() dispose0()
public interface class IDispose0
{
void dispose0() = 0;
};
public ref class CL_pinPtr_Class : public IDispose0 {
public:
CL_pinPtr_Class(int v) : v(v)
{
}
~CL_pinPtr_Class() {
//C#などのDispose()の呼び出しの場合は暗黙のDisposeからここが呼ばれる
System::Diagnostics::Debug::WriteLine(L"~CL_pinPtr_Class デストラクタ {0}" ,this->v);
dispose0();
}
!CL_pinPtr_Class()
{
System::Diagnostics::Debug::WriteLine(L"!CL_pinPtr_Class マネージファイナライザ {0}",this->v);
dispose0();
}
//ref classでは暗黙的にIDisposableが定義されるので再実装はできない
//virtual void Dispose() {
//}
private:
int v;
bool isDisposed=false;
public:
virtual void dispose0() {
System::Diagnostics::Debug::WriteLine(L"\tDispose0");
auto frames = (gcnew System::Diagnostics::StackTrace())->GetFrames();
for each (auto frame in frames)
{
System::Diagnostics::Debug::WriteLine(L"\t\t{0}" , frame->GetMethod());
}
if (isDisposed)
{
return;
}
isDisposed = true;
}
};
void Test(int testtype)
{
CL_pinPtr_Class^ x = gcnew CL_pinPtr_Class(testtype);
auto id = dynamic_cast<IDisposable^>(x);
if (id != nullptr)
{
System::Diagnostics::Debug::WriteLine(L"IDisposableは実装されている");
}
switch (testtype)
{
case 1:
System::Diagnostics::Debug::WriteLine(L"## delete");
delete x;
break;
case 2:
System::Diagnostics::Debug::WriteLine(L"## デストラクタ");
x->~CL_pinPtr_Class();
break;
case 3:
{
System::Diagnostics::Debug::WriteLine(L"## リフレクションで強引にDispose");
auto dispose = x->GetType()->GetMethod(L"Dispose");
dispose->Invoke(x, nullptr);
break;
}
default:
System::Diagnostics::Debug::WriteLine(L"## 明示的な削除をしない場合");
break;
}
x = nullptr;
}
int main(array<System::String^>^ args)
{
{
System::Diagnostics::Debug::WriteLine(L"## スコープから外れるときの自動削除の場合");
CL_pinPtr_Class test(0);
}
{
Test(1);
Test(2);
Test(3);
Test(4);
}
{
CL_pinPtr_Class^ y = gcnew CL_pinPtr_Class(5);
y->Dispose(); //偽インターフェースと#defineを組み合わせた方法
}
}