C++/CLIのメモリ管理

C++: .NET Framework プログラミング最良の言語(via 菊池 Blog)
何となく動作を見たくなったので色々実験。Native C++のデストラクタっぽく動作してくれるところで心が鷲掴みされています。>C++/CLI

#include "stdafx.h"
#include <string>

using namespace System;
using namespace System::Runtime::InteropServices;

ref class Foo {
    String^ name;
public:
    Foo(const char* name) {
        this->name = Marshal::PtrToStringAnsi(static_cast<IntPtr>*1;
    }

    puts("end");

    return 0;
}

/* 結果
call test1
return test1
call test2
~Foo(test2)
return test2
call test3
~Foo(test3)
return test3
call test4
~Foo(test4)
return test4
~Foo(test4)
call test5 1st
~Foo(test5-1)
return test5 1st
call test5 2nd
return test5 2nd
~Foo(test5-2)
end
!Foo(test1)
 */

test4とtest5の結果の差を見るに、%によるtracking referenceは参照カウントを増やさないのかしら?

(追記) メモリというよりリソース管理でしたが、タイトル変えるのもアレなので・・・

*1:char*)name) ); } // コピーコンストラクタは、"クラス名(const クラス名%)" & ではなく % なのに注意 Foo (const Foo% rhs) { this->name = rhs.name; } ~Foo() { Console::WriteLine("~Foo({0})", name); } !Foo() { Console::WriteLine("!Foo({0})", name); } }; void test1() { // GCにお任せ Foo^ foo = gcnew Foo("test1"); } void test2() { // 自分で後始末 Foo^ foo = gcnew Foo("test2"); delete foo; } void test3() { // ^なしだと、スコープを抜けるとDisposeが呼ばれる // Native C++のスタックに確保した場合と似た動作 Foo foo("test3"); } Foo^ test4() { // Disposeされたオブジェクトのハンドルを返している // やっちゃ駄目な例だろう・・・ return %Foo("test4"); } Foo test5(const char* str) { // コピーコンストラクタを定義しないとエラー return Foo(str); } int main(array<System::String ^> ^args) { puts("call test1"); test1(); puts("return test1"); puts("call test2"); test2(); puts("return test2"); puts("call test3"); test3(); puts("return test3"); { puts("call test4"); // 関数のなかでDisposeされる Foo^ foo = test4(); puts("return test4"); // Disposeを更に呼び出し delete foo; } { puts("call test5 1st"); // 関数の中でDisposeされる test5("test5-1"); puts("return test5 1st"); puts("call test5 2nd"); // 関数の中ではDisposeされない Foo foo = test5("test5-2"); puts("return test5 2nd"); // VS2005のバグ? // fatal error C1001: コンパイラで内部エラーが発生しました // Foo(test5("test5-3"