Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Antes do Visual Studio 2005, uma instância de um tipo de referência só podia ser criada usando o new operador , que criava o objeto na pilha de lixo coletada. No entanto, agora você pode criar uma instância de um tipo de referência usando a mesma sintaxe que você usaria para criar uma instância de um tipo nativo na pilha. Assim, você não precisa usar ref new, gcnew para criar um objeto de um tipo de referência. E quando o objeto sai do escopo, o compilador chama o destrutor do objeto.
Observações
Quando se cria uma instância de um tipo de referência usando semântica de stack, o compilador cria internamente a instância no heap gerido por coleta de lixo (usando gcnew).
Quando a assinatura ou o tipo de retorno de uma função inclui uma instância de um tipo de referência por valor, a função será marcada nos metadados como exigindo tratamento especial (com modreq). Atualmente, este tratamento especial é fornecido apenas por clientes Visual C++; outras linguagens não suportam o consumo de funções ou dados que usam tipos de referência criados com semântica de pilha.
Uma razão para usar gcnew (alocação dinâmica) em vez de semântica de pilha seria se o tipo não tem destruidor. Além disso, usar tipos de referência criados com semântica de pilha em assinaturas de função não seria possível se você quiser que suas funções sejam consumidas por linguagens diferentes do Visual C++.
O compilador não gerará um construtor de cópia para um tipo de referência. Portanto, se você definir uma função que usa um tipo de referência por valor na assinatura, deverá definir um construtor de cópia para o tipo de referência. Um construtor de cópia para um tipo de referência tem uma assinatura da seguinte forma: R(R%){}.
O compilador não gerará um operador de atribuição padrão para um tipo de referência. Um operador de atribuição permite criar um objeto usando semântica de pilha e inicializá-lo com um objeto existente criado usando semântica de pilha. Um operador de atribuição para um tipo de referência tem uma assinatura do seguinte formulário: void operator=( R% ){}.
Se o destruidor do seu tipo liberar recursos críticos e o utilizador utilizar semântica de empilhamento para tipos de referência, não será necessário chamar explicitamente o destruidor (ou chamar delete). Para obter mais informações sobre destruidores em tipos de referência, consulte Destruidores e finalizadores em Como definir e consumir classes e estruturas (C++/CLI).
Um operador de atribuição gerado pelo compilador seguirá as regras padrão usuais do C++ com as seguintes adições:
Todos os membros de dados não estáticos cujo tipo é um identificador para um tipo de referência serão copiados superficialmente (tratados como um membro de dados não estáticos cujo tipo é um ponteiro).
Qualquer membro de dados não estáticos cujo tipo seja um tipo de valor será copiado superficialmente.
Qualquer membro de dados não estáticos cujo tipo seja uma instância de um tipo de referência invocará o construtor de cópia do tipo de referência.
O compilador também fornece um % operador unário para converter uma instância de um tipo de referência criado usando semântica de pilha para seu tipo de identificador subjacente.
Os seguintes tipos de referência não estão disponíveis para uso com semântica de _stack_:
Exemplo
Descrição
O exemplo de código a seguir mostra como declarar instâncias de tipos de referência com semântica de pilha, como funcionam o operador de atribuição e o construtor de cópia e como inicializar uma referência de acompanhamento com tipo de referência criado usando semântica de pilha.
Código
// stack_semantics_for_reference_types.cpp
// compile with: /clr
ref class R {
public:
int i;
R(){}
// assignment operator
void operator=(R% r) {
i = r.i;
}
// copy constructor
R(R% r) : i(r.i) {}
};
void Test(R r) {} // requires copy constructor
int main() {
R r1;
r1.i = 98;
R r2(r1); // requires copy constructor
System::Console::WriteLine(r1.i);
System::Console::WriteLine(r2.i);
// use % unary operator to convert instance using stack semantics
// to its underlying handle
R ^ r3 = %r1;
System::Console::WriteLine(r3->i);
Test(r1);
R r4;
R r5;
r5.i = 13;
r4 = r5; // requires a user-defined assignment operator
System::Console::WriteLine(r4.i);
// initialize tracking reference
R % r6 = r4;
System::Console::WriteLine(r6.i);
}
Resultado
98
98
98
13
13