Freigeben über


Handle für Objekt (^) (Komponentenerweiterungen für C++)

Der Handle deklarator ausgesprochen,^ Hut (""), ändert den Typ Bezeichner, dass das Objekt deklariert werden automatisch gelöscht werden soll, wenn das System bestimmt, dass das Objekt nicht mehr zugegriffen werden kann.

Das deklarierte Objekt zugreifen

Eine Variable, die dem Handle deklarator deklariert ist, verhält sich wie ein Zeiger auf das Objekt.Allerdings können die Variable an das gesamte Objekt verweist, nicht auf einem Member des Objekts werden. Außerdem unterstützt keine Zeigerarithmetik.Verwenden Sie den *(Dereferenzierungsoperator), um auf das Objekt zuzugreifen und den Pfeil Member ACCESS-Operator (->), um ein Member des Objekts zuzugreifen.

Windows-Runtime

Der Compiler verwendet den Mechanismus zur COM-Verweiszählungs, um zu bestimmen, ob das Objekt nicht mehr verwendet wird und gelöscht werden kann.Dies ist möglich, da ein Objekt, das von einer Windows Runtime-Schnittstelle abgeleitet wird, tatsächlich ein COM-Objekt ist.Der Verweiszähler erhöht wird, wenn das Objekt erstellt oder kopiert wird und, wenn das Objekt auf NULL festgelegt wird oder dekrementiert den Gültigkeitsbereich verlässt.Wenn der Verweiszähler auf Null wird, wird das Objekt automatisch und sofort gelöscht.

Der Vorteil des Handles deklarators ist der in COM, das Sie den Verweiszähler für ein Objekt explizit verwalten müssen, das ein langwieriger und fehleranfälliger ist.Das heißt, um den Verweiszähler zu erhöhen und verringern müssen Sie das AddRef des Objekts aufrufen () und () - Methoden gemeinsam verwenden.Wenn Sie jedoch ein Objekt mit dem Handle deklarator deklarieren, generiert der Visual C++-Compiler Code, der automatisch den Verweiszähler passt.

Informationen dazu, wie ein Objekt finden Sie unter ref neu instanziiert.

Anforderungen

Compileroption: /ZW

Common Language Runtime

Das System verwendet die CLR-Garbage Collector-Mechanismus, um zu bestimmen, ob das Objekt nicht mehr verwendet wird und gelöscht werden kann.Die Common Language Runtime verwaltet einen Heap, in dem es Objekten zuordnet, und mithilfe verwalteter Verweise (Variablen) in Ihrem Programm an den Speicherort von Objekten im Heap.Wenn ein Objekt nicht mehr verwendet wird, wird der Speicher auf dem Heap gefüllte, freigegeben.In regelmäßigen Abständen komprimiert der Garbage Collector den Heap zu erhöhen, um dem freigegebenen Arbeitsspeicher.Das Komprimieren des Heaps kann Objekte auf dem Heap verschieben, der die Speicherorte ungültig macht, die durch verwaltete Verweise bezeichnet werden.Dennoch berücksichtigt der Garbage Collector den Speicherort für alle verwalteten Verweise und aktualisiert sie automatisch, um die aktuelle Position der Objekte auf dem Heap anzugeben.

Da systemeigene C++-Zeiger (*) und Verweise (&) nicht verwaltete Verweise sind, kann der Garbage Collector die Adressen nicht automatisch aktualisieren, die sie zu zeigen.Um dieses Problem zu beheben, verwenden Sie den Ziehpunkt deklarator um eine Variable anzugeben, dass der Garbage Collector automatisch aktualisiert und darüber im Klaren sein kann.

In Visual C++ 2002 und Visual C++ 2003 wurde __gc * verwendet, um ein Objekt im verwalteten Heap zu deklarieren.^ ersetzt __gc * in der neuen Syntax.

Weitere Informationen finden Sie unter Gewusst wie: Deklarieren von Handles in systemeigenen Typen.

yk97tc08.collapse_all(de-de,VS.110).gifBeispiele

Beispiel

Dieses Beispiel zeigt, wie eine Instanz eines Verweistyps im verwalteten Heap erstellt.In diesem Beispiel wird außerdem veranschaulicht, dass Sie ein Handle mit anderen, zwei Verweise auf dasselbe Objekt in verwaltetem initialisieren können, Heap der Garbage Collection.Beachten Sie, dass nullptr (Komponentenerweiterungen für C++) auf ein Handle zu markiert das Objekt nicht für Garbage Collection.

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

  
  

Beispiel

Im folgenden Beispiel wird gezeigt, wie ein Handle für ein Objekt im verwalteten Heap deklariert, in dem der Typ des Objekts ein geschachtelter Werttyp ist.Im Beispiel wird auch gezeigt, wie der Werttyp des geschachtelten Objekt abgerufen wird.

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

  
  

Beispiel

Dieses Beispiel zeigt, dass das allgemeine C++-Idiom der Verwendung eines Zeigers void* zu der Stelle auf ein beliebiges Objekt durch Object^ ersetzt wird, das ein Handle zu einer Verweisklasse enthalten kann.Darüber hinaus wird gezeigt, dass alle Typen, z. B. Arrays und Delegaten an ein Objekthandle konvertiert werden können.

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

  
  
  

Beispiel

Dieses Beispiel zeigt, dass ein Handle dereferenziert werden kann und ob ein Member über ein dereferenziertes Handle zugegriffen werden kann.

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

  
  

Beispiel

Dieses Beispiel zeigt, dass ein systemeigener Verweis (&) nicht auf int einen Member eines verwalteten Typs gebunden werden kann, wie int möglicherweise im Garbage gesammelten Heap gespeichert wird, und systemeigene Verweise nicht verfolgen - Objekt im verwalteten Heap.Der Korrektur ist, eine lokale Variable zu verwenden, oder & zu % zu ändern, wodurch sie einen Nachverfolgungsverweis.

// 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(de-de,VS.110).gifAnforderungen

Compileroption: /clr

Siehe auch

Referenz

Nachverfolgungsverweisoperator (Komponentenerweiterungen für C++)

Konzepte

Komponentenerweiterungen für Laufzeitplattformen