Compartilhar via


Operador Handle to Object (^) (Extensões de Componentes C++)

O tratar Declarador (^, pronunciado "hat"), modifica o tipo de especificador significa que o objeto declarado deve ser excluído automaticamente quando o sistema determina que o objeto não está mais acessível.

Acessando o objeto declarado

Uma variável declarada com o Declarador alça se comporta como um ponteiro para o objeto.No entanto, a variável aponta para o objeto inteiro, não pode apontar para um membro do objeto e não oferece suporte a aritmética de ponteiro.Use o operador de indireção (*) para acessar o objeto e o operador de acesso de membro de seta (->) para acessar um membro do objeto.

Tempo de Execução do Windows

O compilador usa o COM contagem de referência mecanismo para determinar se o objeto não está sendo usado e pode ser excluído.Isso é possível porque um objeto derivado de uma interface de tempo de execução do Windows é realmente um objeto COM.A contagem de referência é incrementada quando o objeto é criado ou copiado e diminuído quando o objeto é definido como nulo ou fica fora do escopo.Se a contagem de referência vai para zero, o objeto é imediatamente e automaticamente excluído.

A vantagem de Declarador alça é que, em COM você deve gerenciar explicitamente a contagem de referência para um objeto, que é um processo sujeito a erro e entediante.Ou seja, você deve chamar métodos de AddRef () e Release () do objeto para incrementar e decrementar a contagem de referência.No entanto, se você declarar um objeto com o Declarador de alça, o compilador Visual C++ gera código que ajusta automaticamente a contagem de referência.

Para obter informações sobre como criar uma instância de um objeto, consulte ref nova.

Requisitos

Opção de compilador:/ZW

Common Language Runtime

O sistema usa o CLR coletor de lixo mecanismo para determinar se o objeto não está sendo usado e pode ser excluído.O common language runtime mantém uma pilha na qual ele aloca objetos e usa referências gerenciado (variáveis) em seu programa de indicam a localização de objetos no heap.Quando um objeto não é mais usado, a memória ocupada por ela no heap é liberada.Periodicamente, o coletor de lixo compacta a heap para melhor uso memória liberada.Compactação de heap pode mover objetos no heap, invalida o referenciado locais por referências gerenciadas.Entretanto, o coletor de lixo está ciente da localização de todas as referências gerenciadas e atualiza automaticamente para indicar o local atual dos objetos no heap.

Porque ponteiros de C++ nativos (*) e referências (&) não são referências gerenciadas, o coletor de lixo não pode atualizar automaticamente os endereços que eles apontam.Para resolver esse problema, use Declarador alça para especificar uma variável que está ciente do coletor de lixo e pode atualizar automaticamente.

No Visual C++ 2002 e Visual C++ 2003 __gc * foi usado para declarar um objeto no heap gerenciado.O ^ substitui __gc * na nova sintaxe.

Para mais informações, consulte Como: Declare identificadores em tipos nativos.

yk97tc08.collapse_all(pt-br,VS.110).gifExemplos

Exemplo

Este exemplo mostra como criar uma instância de um tipo de referência no heap gerenciado.Esse exemplo também mostra que você pode inicializar um identificador com o outro, resultando em duas referências ao mesmo objeto no heap gerenciado, coleta de lixo.Observe que atribuindo nullptr (Extensões de Componentes C++) um identificador não marca o objeto para coleta de lixo.

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

Saída

  
  

Exemplo

O exemplo a seguir mostra como declarar um identificador para um objeto no heap gerenciado, onde o tipo de objeto é um tipo de valor convertidos.O exemplo também mostra como obter o tipo de objeto in a box.

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

Saída

  
  

Exemplo

Este exemplo mostra o idioma de C++ comuns do uso de um ponteiro void * para apontar para um objeto arbitrário é substituído pelo objeto ^, que pode conter um identificador para qualquer classe de referência.Ele também mostra que todos os tipos, tais como matrizes e delegados, podem ser convertidos em um identificador 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);
}

Saída

  
  
  

Exemplo

Esse exemplo mostra que um identificador de referência pode ser cancelado e que um membro pode ser acessado por meio de uma alça dereferenced.

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

Saída

  
  

Exemplo

Esse exemplo mostra que uma referência nativa (&) não é possível vincular a um int membro de um tipo gerenciado, como o int pode ser armazenado no heap coletado de lixo e referências nativas não rastreiam o movimento do objeto no heap gerenciado.A correção é usar uma variável local ou alterar & para %, tornando-se uma referência de rastreamento.

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

Opção de compilador:/clr

Consulte também

Referência

Operador de Referência de Acompanhamento (Extensões de Componentes C++)

Conceitos

Extensões de componente para plataformas de tempo de execução