Поделиться через


Оператор дескриптора объекта (^) (расширения компонентов C++)

Декларатор маркера (произнесенное ^«шлему»), изменяет тип описатель для означать, что объявленный объект должен быть автоматически удаляется, когда система указывает, что объект более не доступен.

Доступ к объявленному объект

Переменная, которая объявлена с декларатором маркера ведет себя как указатель на объект.Однако переменные точки ко всему объекту, не могут указывать на член объекта, а он не поддерживает арифметические операции указателя.Использовать косвенный оператор (*) для доступа к объекту, а оператор доступа к членам -> стрелки () для доступа к члену объекта.

Среда выполнения Windows

Компилятор использует COM-механизм подсчета ссылок для определения, используется ли объект и можно ли его удалить.Это возможно, поскольку объект, производный от интерфейса среды выполнения окон фактически COM-объект.Увеличивается при создании или скопирован объект, и уменьшается число ссылок если объект имеет значение null или выходит из области.Если значение счетчика ссылок становится равным нулю, то объект автоматически и немедленно удаляется.

Преимущество декларатора маркера то в модели COM необходимо явно управлять счетчик ссылок для объекта, который нудный и подверженный ошибкам процесс.Иными словами, для увеличения и уменьшения счетчика ссылок необходимо вызвать AddRef объекта () и освобождение () методы.Однако если объявить объект с декларатором маркера, то компилятор Visual C++ создает код, который автоматически обрабатывает счетчика ссылок.

Дополнительные сведения о способах создания экземпляра объекта см. в разделе ref новый.

Требования

Параметр компилятора: /ZW

Среда CLR

Система использует механизм сборщика мусора среды CLR для определения, является ли объект больше не используется и не может быть удален.Среда CLR поддерживает кучу, на которой оно выделяет объекты, и использовать управляемые ссылки на переменные () в программе отображает расположение объектов в куче.Когда объект больше не используется, память, которую она заняла в куче освобождается.Периодически сборщик мусора куча сжимается для улучшения использование освобоженная память.Сжатие куча может перемещать объекты в куче, которая делает недействительным расположения сосланные в управляемый ссылкам.Однако сборщик мусора узнает об расположения всех управляемых ссылок и обновляет их автоматически, чтобы отобразить текущее расположение объектов в куче.

Поскольку собственные указатели C++ (*) и ссылки (&) не является, управляемых ссылок, сборщик мусора не может автоматически обновить адреса они указывают на.Чтобы решить эту проблему, используйте декларатор маркера, чтобы указать переменную, что сборщик мусора узнает об и может обновлять автоматически.

В Visual C++ 2002 и Visual C++ 2003 __gc * использованный для объявления объект в управляемой куче.^ заменяет __gc * в новом синтаксисе.

Дополнительные сведения см. в разделе Практическое руководство. Объявление дескрипторов в собственных типах.

yk97tc08.collapse_all(ru-ru,VS.110).gifПримеры

Пример

В этом образце показано, как создать экземпляр ссылочного типа в управляемой куче.В этом образце также показано, что можно инициализировать один маркер с другими, в результате чего 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
}

yk97tc08.collapse_all(ru-ru,VS.110).gifТребования

Параметр компилятора: /clr

См. также

Ссылки

Оператор отслеживания ссылок (расширения компонентов C++)

Основные понятия

Расширения компонентов для платформ среды выполнения