Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The latest version of this topic can be found at Tracking Reference Operator (C++ Component Extensions).
A tracking reference (%
) behaves like an ordinary C++ reference (&
) except that when an object is assigned to a tracking reference, the object’s reference count is incremented.
All Platforms
A tracking reference has the following characteristics.
Assignment of an object to a tracking reference causes the object’s reference count to be incremented.
A native reference (&) is the result when you dereference a *. A tracking reference (%) is the result when you dereference a ^. As long as you have a % to an object, the object will stay alive in memory.
The dot (
.
) member-access operator is used to access a member of the object.Tracking references are valid for value types and handles (for example
String^
).A tracking reference cannot be assigned a null or
nullptr
value. A tracking reference may be reassigned to another valid object as many times as required.A tracking reference cannot be used as a unary take-address operator.
Windows Runtime
A tracking reference behaves like a standard C++ reference, except that a % is reference-counted. The following snippet shows how to convert between % and ^ types:
Foo^ spFoo = ref new Foo();
Foo% srFoo = *spFoo;
Foo^ spFoo2 = %srFoo;
The following example shows how to pass a ^ to a function that takes a %.
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); }
}
Common Language Runtime
In C++/CLI, you can use a tracking reference to a handle when you bind to an object of a CLR type on the garbage-collected heap.
In the CLR, the value of a tracking reference variable is updated automatically whenever the garbage collector moves the referenced object.
A tracking reference can be declared only on the stack. A tracking reference cannot be a member of a class.
It is not possible to have a native C++ reference to an object on the garbage-collected heap.
For more information about tracking references in C++/CLI, see:
Examples
Example
The following sample for C++/CLI shows how to use a tracking reference with native and managed types.
// 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;
}
Example
The following sample for C++/CLI shows how to bind a tracking reference to an array.
// 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]);
}
Output
21
222