Udostępnij za pośrednictwem


Operator uchwytu do obiektu (^) (C++ Component Extensions)

Deklarator obsługi (^, wymawiane „hat”), modyfikuje typ specyfikator, aby wskazać, że deklarowany obiekt powinien być automatycznie usuwany, gdy system określi, że nie jest on już dostępny.

Dostęp do deklarowanego obiektu

Zmienna, która jest zadeklarowana za pomocą oświadczenie uchwytu, zachowuje się jak wskaźnik do obiektu.Jednak punkty zmienne do całego obiektu nie mogą odnosić się do elementu członkowskiego obiektu, a nie obsługują operacji arytmetycznych wskaźnika.Użyj operatora poziomu pośredniego (*), aby uzyskać dostęp do obiektu i operatora strzałki dostępu do elementu członkowskiego (->), aby uzyskać dostępu do członka obiektu.

Środowisko wykonawcze systemu Windows

Kompilator używa mechanizmu licznika odwołań COM, aby ustalić, czy obiekt jest już używany i czy może być usunięty.Jest to możliwe, ponieważ obiekt pochodzący z interfejsu środowiska wykonawczego systemu Windows jest w rzeczywistości obiektem COM.Licznik odwołań rośnie, gdy obiekt jest utworzony lub skopiowany i zmniejszony, kiedy obiekt jest ustawiony na wartość null lub poza zakresem.Jeśli licznik odwołań zbliża się do zera, obiekt jest automatycznie i bezzwłocznie usuwany.

Zaletą deklaratora uchwytu jest to, że w modelu COM musi jawnie zarządzać licznikiem odwołań do obiektu, który jest procesem żmudnym i podatnym na błędy.Oznacza to, że aby zwiększać i zmniejszać liczbę odwołań, należy wywołać metody AddRef() i Release() obiektu.Jednak jeśli obiekt został zadeklarowany za pomocą deklaratora uchwytu, kompilator języka Visual C++ generuje kod, który automatycznie dostosowuje licznika odwołań.

Aby uzyskać informacje dotyczące sposobu tworzenia wystąpienia obiektu, zobacz ref new.

Wymagania

Opcja kompilatora: /ZW

Środowisko uruchomieniowe języka wspólnego

System używa mechanizmu modułu odśmiecania pamięci CLR, aby ustalić, czy obiekt jest już używany i czy może być usunięty.Środowisko uruchomieniowe języka wspólnego utrzymuje stertę, do której przydziela obiekty, i korzysta z zastosowań zarządzanych odwołania (zmiennych) w programie wskazujących lokalizację obiektów na stosie.Jeśli obiekt nie jest już używany, pamięć, którą zajmował na stercie, jest zwalniana.Okresowo moduł odśmiecania pamięci kompaktuje stos w celu lepszego wykorzystania zwolnionej pamięci.Przy kompaktowaniu stosu obiekty można przenosić na stosie, co unieważnia lokalizacje przewidziane przez zarządzane odwołania.Jednak moduł odśmiecania pamięci zna lokalizację wszystkich zarządzanych odwołań i automatycznie aktualizuje je, aby wskazać bieżące położenie obiektów na stosie.

Ponieważ wskaźniki natywne C++ (*) i odwołania (&) nie są zarządzanymi odniesieniami, moduł odśmiecania pamięci nie może automatycznie zaktualizować adresów, na które one wskazują.Aby rozwiązać ten problem, użyj deklaratora uchwytu, aby określić zmienną, którą będzie wykorzystywał moduł odśmiecania pamięci i którą można będzie automatycznie aktualizować.

W programach Visual C++ 2002 i Visual C++ 2003 __gc * został użyty do deklarowania go jako obiekt na stosie zarządzanym. ^ zastępuje __gc * w nowej składni.

Aby uzyskać więcej informacji, zobacz Porady: deklarowanie dojść w typach natywnych.

Przykłady

Przykład

Ten przykład pokazuje, jak utworzyć wystąpienia typu odwołania na stosie elementów bezużytecznych. Przykład ten pokazuje również, że można zainicjować określone dojście w innym, co spowoduje dwa odwołania do samego obiektu na zarządzanych stosach modułu odśmiecania pamięci.Należy zauważyć, że przypisanie nullptr (C++ Component Extensions) do określonego dojścia nie oznacza obiektu do wyrzucania elementów bezużytecznych.

// 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();   
}

Dane wyjściowe

12

Przykład

Poniższy przykład pokazuje sposób deklarowania dojścia do obiektu na stosie zarządzanym, gdzie typ obiektu jest typem wartości w ramkach.Próbka pokazuje również, jak uzyskać typ wartości z obiektu w ramce.

// 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);
}

Dane wyjściowe

  
  

Przykład

Ten przykład pokazuje, że wspólny idiom języka C++ użycia punktu do dowolnego obiektu za pomocą wskaźnika void* jest zastępowany przez obiekt ^, który ma dojścia do każdej klasy odniesienia.Pokazuje również, że wszystkie typy, takie jak tablice i pełnomocnicy, mogą być konwertowane na uchwyt obiektu.

// 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);
}

Dane wyjściowe

  
  
  

Przykład

Ten przykład pokazuje, że można usunąć uchwyt odwołania i że można uzyskać dostęp do elementu członkowskiego za pośrednictwem usuniętego uchwytu odwołania.

// 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
}

Dane wyjściowe

  
  

Przykład

Ten przykład pokazuje, że odwołania natywnego (&) nie można powiązać z elementem członkowskim int typu zarządzanego, a int mogą być przechowywane w stosie modułu odśmiecania pamięci i odwołania natywne nie śledzą ruchu obiektu w stosie zarządzanym.Poprawka jest używana do zmiennej lokalnej lub po to, aby zmienić & na %, dzięki czemu będzie to śledzenie odwołania.

// 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
}

Wymagania

Opcja kompilatora: /clr

Zobacz też

Informacje

Operator odwołania śledzenia (C++ Component Extensions)

Koncepcje

Component Extensions dla platform środowiska uruchomieniowego