Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

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.

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 ^. The only difference between & and % is that where & is a “raw” reference, % is a reference-counted reference. 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.

  • A tracking reference can be declared only on the stack. A tracking reference cannot be a member of a class.

  • 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.

A tracking reference behaves like a reference-counted standard C++ reference. For information about C++ references, see References (C++).

The following example shows how to use a tracking reference to modify the contents of the object it points to.

/ZW
using namespace Platform;
int main()
{
array<String^> ^arr = ref new array<String^>(10);
    int i = 0;

    for(int i = 0; i < 10; ++i){ 
        String^& s = arr[i];
        s = i++.ToString(); // changes the array content
    }
}

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.

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:

Example

The following sample 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 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

21222
Show:
© 2015 Microsoft