参照演算子の追跡 (C++/CLI および C++/CX)
"追跡参照" (%
) は、通常の C++ 参照 (&
) のように動作します。ただし、オブジェクトが追跡参照に割り当てられている場合は、オブジェクトの参照カウントがインクリメントされます。
すべてのプラットフォーム
追跡参照には次の特徴があります。
オブジェクトを追跡参照に代入すると、オブジェクトの参照カウントがインクリメントされます。
ネイティブ参照 (
&
) は*
を逆参照した結果です。 追跡参照 (%
) は^
を逆参照した結果です。 オブジェクトに対する%
がある限り、そのオブジェクトはメモリに残り続けることになります。ドット (
.
) メンバー アクセス演算子は、オブジェクトのメンバーにアクセスするために使用されます。追跡参照は、値型およびハンドル (たとえば
String^
) に対して有効です。追跡参照に null 値や
nullptr
値を代入することはできません。 追跡参照は、必要に応じて何度でも、別の有効なオブジェクトに再割り当てされる場合があります。追跡参照は、アドレスを受け取る単項演算子としては使用できません。
Windows ランタイム
追跡参照は、% が参照カウントされている点を除くと、標準 C++ 参照のように動作します。 次のスニペットでは、% 型と ^ 型の間で変換を行う方法を示します。
Foo^ spFoo = ref new Foo();
Foo% srFoo = *spFoo;
Foo^ spFoo2 = %srFoo;
次の例では、% を受け取る関数に ^ を渡す方法を示します。
ref class Foo sealed {};
// internal or private
void UseFooHelper(Foo% f)
{
auto x = %f;
}
// public method on ABI boundary
void UseFoo(Foo^ f)
{
if (f != nullptr) { UseFooHelper(*f); }
}
共通言語ランタイム
C++/CLI では、ガベージ コレクション ヒープ上の CLR 型オブジェクトにバインドする場合、ハンドルへの追跡参照を使用できます。
CLR では、ガベージ コレクターが参照先オブジェクトを移動させるたびに、追跡参照変数の値が自動的に更新されます。
追跡参照はスタック上でのみ宣言できます。 追跡参照をクラスのメンバーにすることはできません。
ガベージ コレクション ヒープ上のオブジェクトへのネイティブ C++ 参照を持つことはできません。
C++/CLI での追跡参照の詳細については、以下を参照してください。
例
次の C++/CLI の例では、ネイティブ型およびマネージド型で追跡参照を使用する方法を示します。
// tracking_reference_1.cpp
// compile with: /clr
ref class MyClass {
public:
int i;
};
value struct MyStruct {
int k;
};
int main() {
MyClass ^ x = ref new MyClass;
MyClass ^% y = x; // tracking reference handle to reference object
int %ti = x->i; // tracking reference to member of reference type
int j = 0;
int %tj = j; // tracking reference to object on the stack
int * pi = new int[2];
int % ti2 = pi[0]; // tracking reference to object on native heap
int *% tpi = pi; // tracking reference to native pointer
MyStruct ^ x2 = ref new MyStruct;
MyStruct ^% y2 = x2; // tracking reference to value object
MyStruct z;
int %tk = z.k; // tracking reference to member of value type
delete[] pi;
}
次の C++/CLI の例では、配列に追跡参照をバインドする方法を示します。
// tracking_reference_2.cpp
// compile with: /clr
using namespace System;
int main() {
array<int> ^ a = ref new array<Int32>(5);
a[0] = 21;
Console::WriteLine(a[0]);
array<int> ^% arr = a;
arr[0] = 222;
Console::WriteLine(a[0]);
}
21
222