{{indexmenu_n>10}}
====== interior_ptr ======
interior_ptrはマネージヒープ上にあるvalue typeや基本型を指すためのポインタです。
以下のコードを考えます。
ref class R
{
public:
Object o;
int i;
};
void set100(int* i)
{
*i = 100;
}
int main()
{
R^ r = gcnew R;
set100(&r->i);
}
このコードはset100()でエラーになります。マネージヒープ上にあるものはポインタで受け取ることはできません。マネージヒープ上のデータはいつ場所が変わるかわからないため、純粋なアドレスを保持するポインタではまずいのです。
そこで以下のようにして見ます。
ref class R
{
public:
Object o;
int i;
};
void set100(int^ i)
{
i = 100;
}
int main()
{
R^ r = gcnew R;
set100(r->i);
}
こうするとset100()のところではr->iはボックス化されてしまい、100がセットされるのは、新しく作られたintインスタンスに対してです。このインスタンスはいずれ捨てられてしまいます。
そこでinterior_ptrを用いて以下のように書きます。
ref class R
{
public:
Object o;
int i;
};
void set100(interior_ptr i)
{
*i = 100;
}
int main()
{
R^ r = gcnew R;
set100(&r->i);
}
これでr->iを変更することができます。また普通のint*をset100()に渡すこともできます。
また、トラッキング参照を用いて以下のように書くこともできます。
ref class R
{
public:
Object o;
int i;
};
void set100(int% i)
{
i = 100;
}
int main()
{
R^ r = gcnew R;
set100(r->i);
}
トラッキング参照も、普通のintを受け取ることができます。