Оператор дескриптора объекта (^) (расширения компонентов C++)
Декларатор маркера (произнесенное ^«шлему»), изменяет тип описатель для означать, что объявленный объект должен быть автоматически удаляется, когда система указывает, что объект более не доступен.
Доступ к объявленному объект
Переменная, которая объявлена с декларатором маркера ведет себя как указатель на объект.Однако переменные точки ко всему объекту, не могут указывать на член объекта, а он не поддерживает арифметические операции указателя.Использовать косвенный оператор (*) для доступа к объекту, а оператор доступа к членам -> стрелки () для доступа к члену объекта.
Среда выполнения Windows
Компилятор использует COM-механизм подсчета ссылок для определения, используется ли объект и можно ли его удалить.Это возможно, поскольку объект, производный от интерфейса среды выполнения окон фактически COM-объект.Увеличивается при создании или скопирован объект, и уменьшается число ссылок если объект имеет значение null или выходит из области.Если значение счетчика ссылок становится равным нулю, то объект автоматически и немедленно удаляется.
Преимущество декларатора маркера то в модели COM необходимо явно управлять счетчик ссылок для объекта, который нудный и подверженный ошибкам процесс.Иными словами, для увеличения и уменьшения счетчика ссылок необходимо вызвать AddRef объекта () и освобождение () методы.Однако если объявить объект с декларатором маркера, то компилятор Visual C++ создает код, который автоматически обрабатывает счетчика ссылок.
Дополнительные сведения о способах создания экземпляра объекта см. в разделе ref новый.
Требования
Параметр компилятора: /ZW
Среда CLR
Система использует механизм сборщика мусора среды CLR для определения, является ли объект больше не используется и не может быть удален.Среда CLR поддерживает кучу, на которой оно выделяет объекты, и использовать управляемые ссылки на переменные () в программе отображает расположение объектов в куче.Когда объект больше не используется, память, которую она заняла в куче освобождается.Периодически сборщик мусора куча сжимается для улучшения использование освобоженная память.Сжатие куча может перемещать объекты в куче, которая делает недействительным расположения сосланные в управляемый ссылкам.Однако сборщик мусора узнает об расположения всех управляемых ссылок и обновляет их автоматически, чтобы отобразить текущее расположение объектов в куче.
Поскольку собственные указатели C++ (*) и ссылки (&) не является, управляемых ссылок, сборщик мусора не может автоматически обновить адреса они указывают на.Чтобы решить эту проблему, используйте декларатор маркера, чтобы указать переменную, что сборщик мусора узнает об и может обновлять автоматически.
В Visual C++ 2002 и Visual C++ 2003 __gc * использованный для объявления объект в управляемой куче.^ заменяет __gc * в новом синтаксисе.
Дополнительные сведения см. в разделе Практическое руководство. Объявление дескрипторов в собственных типах.
Примеры
Пример
В этом образце показано, как создать экземпляр ссылочного типа в управляемой куче.В этом образце также показано, что можно инициализировать один маркер с другими, в результате чего 2 ссылках на один и тот же объект, мусор-собранной в управляемой куче.Обратите внимание, что при присвоении nullptr (расширения компонентов C++) на один дескриптор не помечает объект для сборки мусора.
// mcppv2_handle.cpp
// compile with: /clr
ref class MyClass {
public:
MyClass() : i(){}
int i;
void Test() {
i++;
System::Console::WriteLine(i);
}
};
int main() {
MyClass ^ p_MyClass = gcnew MyClass;
p_MyClass->Test();
MyClass ^ p_MyClass2;
p_MyClass2 = p_MyClass;
p_MyClass = nullptr;
p_MyClass2->Test();
}
Output
Пример
В следующем образце показано, как объявить дескриптор объекта в управляемой куче, где тип объекта упакованный тип значения.В образце также показано, как получить тип значения из положенного в упакован объекта.
// mcppv2_handle_2.cpp
// compile with: /clr
using namespace System;
void Test(Object^ o) {
Int32^ i = dynamic_cast<Int32^>(o);
if(i)
Console::WriteLine(i);
else
Console::WriteLine("Not a boxed int");
}
int main() {
String^ str = "test";
Test(str);
int n = 100;
Test(n);
}
Output
Пример
В этом образце показано, что общий идиоматизм C++ использования указателя void* к точке к произвольному объекту заменен Object^, которое может содержать дескриптор к любому классу ссылки.Он также указывает на то, что все типы, такие как массивы и делегаты можно преобразовать в маркер объекта.
// mcppv2_handle_3.cpp
// compile with: /clr
using namespace System;
using namespace System::Collections;
public delegate void MyDel();
ref class MyClass {
public:
void Test() {}
};
void Test(Object ^ x) {
Console::WriteLine("Type is {0}", x->GetType());
}
int main() {
// handle to Object can hold any ref type
Object ^ h_MyClass = gcnew MyClass;
ArrayList ^ arr = gcnew ArrayList();
arr->Add(gcnew MyClass);
h_MyClass = dynamic_cast<MyClass ^>(arr[0]);
Test(arr);
Int32 ^ bi = 1;
Test(bi);
MyClass ^ h_MyClass2 = gcnew MyClass;
MyDel^ DelInst = gcnew MyDel(h_MyClass2, &MyClass::Test);
Test(DelInst);
}
Output
Пример
В этом образце показано, что дескриптор может быть разыменован и что участник может осуществляться через разыменованный дескриптор.
// mcppv2_handle_4.cpp
// compile with: /clr
using namespace System;
value struct DataCollection {
private:
int Size;
array<String^>^ x;
public:
DataCollection(int i) : Size(i) {
x = gcnew array<String^>(Size);
for (int i = 0 ; i < Size ; i++)
x[i] = i.ToString();
}
void f(int Item) {
if (Item >= Size)
{
System::Console::WriteLine("Cannot access array element {0}, size is {1}", Item, Size);
return;
}
else
System::Console::WriteLine("Array value: {0}", x[Item]);
}
};
void f(DataCollection y, int Item) {
y.f(Item);
}
int main() {
DataCollection ^ a = gcnew DataCollection(10);
f(*a, 7); // dereference a handle, return handle's object
(*a).f(11); // access member via dereferenced handle
}
Output
Пример
В этом образце показано, что собственную ссылку (&) не удается привязать к элементу int управляемого типа, как int может храниться в куче собранной мусором и собственные ссылки не отслеживают перемещение объектов в управляемой куче.Исправление использовать локальную переменную или изменить & к %, что ему ссылку отслеживания.
// mcppv2_handle_5.cpp
// compile with: /clr
ref struct A {
void Test(unsigned int &){}
void Test2(unsigned int %){}
unsigned int i;
};
int main() {
A a;
a.i = 9;
a.Test(a.i); // C2664
a.Test2(a.i); // OK
unsigned int j = 0;
a.Test(j); // OK
}
Требования
Параметр компилятора: /clr
См. также
Ссылки
Оператор отслеживания ссылок (расширения компонентов C++)