C++ de pilha semântica para tipos de referência
Antes do Visual C++ 2005, uma instância de um tipo de referência pode apenas ser criada usando o operador de new , que criou o objeto no heap coletado como lixo.No entanto, agora você pode criar uma instância de um tipo de referência usando a mesma sintaxe que você deve usar para criar uma instância de um tipo nativo na pilha.Portanto, você não precisa usar ref new, gcnew (Extensões de Componentes C++) para criar um objeto de um tipo de referência.Quando o objeto e sai do escopo, o compilador chama o destrutor do objeto.
Comentários
Quando você cria uma instância de um tipo de referência usando a semântica de pilha, o compilador cria internamente a instância na heap coletado como lixo (usando gcnew).
Quando a assinatura ou o tipo de retorno de uma função incluem uma instância de um tipo de referência por valor, a função será marcada como nos metadados a exigência de tratamento especial (com modreq).Essa manipulação especial é fornecida atualmente somente por clientes do Visual C++; outros idiomas atualmente não suportam consumir funções ou dados que são tipos de referência de uso criados com a semântica de pilha.
Uma razão para usar gcnew alocação dinâmico () em vez de semântica de pilha seria se o tipo não tem nenhum destrutor.Além disso, usar tipos de referência criados com a semântica de pilha em assinaturas de função não seria possível se você deseja suas funções a ser consumidas por diferentes idiomas Visual C++.
O compilador não irá gerar um construtor de impressão para um tipo de referência.Como consequência, se você define uma função que use uma referência a por valor tipo na assinatura, você deve definir um construtor de impressão para o tipo de referência.Um construtor de impressão 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 que você crie um objeto usando a semântica de pilha e inicializá-la com um objeto existente criado usando a semântica de pilha.Um operador de atribuição para um tipo de referência tem uma assinatura da seguinte forma: void operator=( R% ){}){}.
Se o destrutor do tipo o libera recursos críticos e semântica da pilha de uso para tipos de referência, você não precisará chamar explicitamente o destrutor (ou chamar delete).Para obter mais informações sobre os destruidores em tipos de referência, consulte Destruidores e finalizadores em Visual C++.
Um operador de atribuição compilador-geradas irá seguir as regras normais de C++ padrão com as seguintes adições:
Todos os membros de dados não-estático cujo tipo é um identificador para um tipo de referência rasos serão copiados (tratado como um membro de dados não-estático cujo tipo é um ponteiro).
Qualquer membro de dados não-estático cujo tipo é um tipo de valor raso será copiado.
Qualquer membro de dados não-estático cujo tipo é uma instância de um tipo de referência chamar uma chamada para o construtor de impressão de tipo de referência.
O compilador também fornece um operador unário de % para converter uma instância de um tipo de referência criado usando a semântica de pilha para seu tipo subjacente de manipular.
Os seguintes tipos de referência não estão disponíveis para uso com semântica de pilha:
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 o construtor de operador de atribuição e de impressão, e como inicializar uma referência de rastreamento com o tipo de referência criado usando a 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);
}
Saída
98
98
98
13
13