Compartir a través de


Operador de identificador de objeto (^) (Extensiones de componentes de C++)

El declarador del identificador (^, pronunciado “sombrero”), modificar el tipo especificador para indicar que el objeto declarado debe automáticamente eliminarse cuando el sistema determina que el objeto no es más accesible.

Acceso a objetos declarado

Una variable que se declara con el declarador de identificador se comporta como un puntero al objeto.Sin embargo, los puntos variables al objeto completo, no pueden apuntar a un miembro del objeto, y no admite la aritmética con punteros.Utilice el operador de direccionamiento indirecto (*) para tener acceso al objeto, y el operador de acceso a miembros de flecha (->) para tener acceso a un miembro del objeto.

Windows en tiempo de ejecución

El compilador utiliza la referencia COM que cuenta el mecanismo para determinar si el objeto se utiliza y no más eliminarse.Esto es posible porque un objeto que es derivado de una interfaz en tiempo de ejecución de Windows es realmente un objeto COM.Se incrementa cuando se crea o se copia el objeto, y se decrementa cuando el objeto se establece en null o sale del ámbito.Si el recuento de referencias va a cero, el objeto automáticamente y se elimina inmediatamente.

La ventaja de declaradores ID es que en COM que debe explícitamente administrar el recuento de referencias para un objeto, que es un proceso tedioso y propenso a errores.Es decir, para aumentar y para disminuir el recuento de referencias debe llamar AddRef del objeto () y liberar () métodos.Sin embargo, si declara un objeto con el declarador de identificador, el compilador de Visual C++ genera código que incluye automáticamente al recuento de referencias.

Para obtener información sobre cómo crear instancias de un objeto, vea referencia nueva.

Requisitos

Opción del compilador: /ZW

Common Language Runtime

El sistema utiliza el mecanismo del recolector de elementos no utilizados de CLR para determinar si el objeto se utiliza y no más eliminarse.Common Language Runtime mantiene una pila donde asigna objetos, y usa las referencias administradas (variables) del programa indica la ubicación de objetos en el montón.Cuando un objeto ya no se usa, se libera la memoria que el en la pila.Periódicamente, el recolector de elementos no utilizados compacta la pila para mejorar uso memoria liberada.Compactar la pila puede mover objetos del montón, que reemplaza las ubicaciones a por referencias administradas.Sin embargo, el recolector de elementos no utilizados es consciente de la ubicación de todas las referencias administradas, y automáticamente las actualizaciones para indicar la ubicación actual de los objetos en el montón.

Dado que los punteros de C++ nativo (*) y referencias (&) no son referencias administradas, el recolector de elementos no utilizados no puede actualizar automáticamente las direcciones que elija.Para solucionar este problema, utilice el declarador ID para especificar una variable que el recolector de elementos no utilizados es consciente de y puede actualizar automáticamente.

En Visual C++ 2002 y Visual C++ 2003, __gc * se utiliza para declarar un objeto del montón administrado.^ reemplaza __gc * en la nueva sintaxis.

Para obtener más información, vea Cómo: Declarar controladores en tipos nativos.

yk97tc08.collapse_all(es-es,VS.110).gifEjemplos

Ejemplo

Este ejemplo muestra cómo crear una instancia de un tipo de referencia en el montón administrado.Este ejemplo también se muestra que puede inicializar un identificador con otro, por lo que dos referencias al mismo objeto en el montón administrado, de recolección de elementos no utilizados.Observe que asignar nullptr (Extensiones de componentes de C++) un identificador no marca el objeto para la recolección de elementos no utilizados.

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

  
  

Ejemplo

El ejemplo siguiente se muestra cómo declarar un identificador a un objeto del montón administrado, donde es un tipo de valor el tipo de objeto convertido.El ejemplo también se muestra cómo obtener el tipo de valor de conversión boxing.

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

  
  

Ejemplo

Este ejemplo muestra que la frase expresiones comunes de C++ mediante un puntero de void* para que señale a un objeto arbitrario es reemplazada por Object^, que puede contener un identificador a cualquier tipo de referencia.También se muestra que todos los tipos, tales como matrices y delegados, pueden convertirse en un controlador de objeto.

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

  
  
  

Ejemplo

Este ejemplo muestra que un identificador puede desreferenciar y un miembro puede tener acceso mediante un identificador administrada.

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

  
  

Ejemplo

Este ejemplo muestra una referencia nativa (&) no se puede enlazar a int a un miembro de un tipo administrado, como int podría almacenarse en la pila de recolección, y referencias nativas no siguen el movimiento de objetos en el montón administrado.La corrección es utilizar una variable local, o cambiar & a %, en una referencia de seguimiento.

// 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(es-es,VS.110).gifRequisitos

Opción del compilador: /clr

Vea también

Referencia

Operador de referencia de seguimiento (Extensiones de componentes de C++)

Conceptos

Extensiones de componentes para plataformas de tiempo de ejecución