Partilhar via


Semântica da pilha do C++ para tipos de referência

Antes do Visual C++ 2005, uma instância de um tipo de referência só pode ser criada usando o operador de new , que criou o objeto no heap coletado lixo. 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 (Extensões de Componentes C++) para criar um objeto de tipo de referência. Quando o objeto e sair do escopo, o compilador chama o destruidor do objeto.

Comentários

Quando você cria uma instância de um tipo de referência usando a semântica da pilha, o compilador cria internamente a instância no heap coletado 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 do valor, a função será marcada nos metadados como a exigência de manipulação especial (com modreq). Esse tratamento especial é fornecida atualmente apenas pelos clientes do Visual C++; outros idiomas não dão suporte a funções ou atualmente consumir dados que os tipos de referência de uso criados com a semântica da pilha.

Uma razão para usar gcnew (alocação dinâmica) em vez da semântica da pilha será se o tipo não tem nenhum destruidor. Além disso, usar os tipos de referência criados com a semântica da pilha em assinaturas de função não será possível se você deseja suas funções serem consumidas por idiomas diferentes do Visual C++.

O compilador não gerará um construtor de cópia para um tipo de referência. Em virtude disso, se você definir uma função que usa uma referência de digitar o valor na assinatura, você deve 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 que você crie um objeto usando a semântica da pilha e para inicializá-lo a um objeto existente criado com a semântica da pilha. Um operador de atribuição de um tipo de referência tem uma assinatura da seguinte forma: void operator=( R% ){}.

Se o seu tipo destruidor do libera recursos críticos e semântica da pilha de uso para tipos de referência, você não precisa chamar explicitamente o destruidor (ou chame delete). Para obter mais informações sobre os destruidores em tipos de referência, consulte Destruidores e finalizadores no Visual C++.

Um operador de atribuição completo gerado segue as regras comuns padrão do C++ com as adições a seguir:

  • Todos os membros de dados que não sejam estáticos cujo tipo é um identificador em um tipo de referência rasos serão copiados (tratado como um membro de dados que não sejam estáticos cujo tipo é um ponteiro).

  • O membro all de dados que não sejam estáticos cujo tipo é de um tipo de valor será copiado shallow.

  • O membro all de dados que não sejam estáticos cujo tipo é uma instância de um tipo de referência invocará uma chamada para o construtor de cópia do 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 com a semântica da pilha ao seu tipo subjacente do identificador.

Os seguintes tipos de referência não estão disponíveis para uso com semântica da pilha:

Exemplo

Descrição

O exemplo de código mostra como declarar instâncias de tipos de referência com semântica da pilha, como o construtor do operador de atribuição e de cópia, e como inicializar uma referência de controle com o tipo de referência criado com a semântica da 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

Consulte também

Referência

Classes e Estruturas (Extensões de Componentes C++)