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.
Exemplos
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
}
Requisitos
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