Condividi tramite


Semantica dello stack C++ per i tipi di riferimento

Prima di Visual C++ 2005, un'istanza di un tipo di riferimento venga creata solo utilizzando l'operatore di new, che ha creato l'oggetto nell'heap sottoposto a garbage collection.Tuttavia, è ora possibile creare un'istanza di un tipo di riferimento utilizzando la stessa sintassi che viene utilizzata per creare un'istanza di un tipo nativo nello stack.Pertanto, non è necessario utilizzare ref new, gcnew (Estensioni del componente C++) per creare un oggetto di un tipo di riferimento.E quando l'oggetto area di validità, il compilatore chiama il distruttore di oggetti.

Note

Quando si crea un'istanza di un tipo di riferimento mediante la semantica dello stack, il compilatore crea internamente l'istanza nell'heap sottoposto a garbage collection mediante gcnew).

Quando la firma o il tipo restituito di una funzione include un'istanza di un tipo riferimento per valori, la funzione verrà contrassegnata nei metadati come richieste di gestione speciale (con modreq).Questa gestione speciale attualmente disponibile solo per i client di Visual C++, altri linguaggi non supportano attualmente utilizzare le funzioni o dati che utilizzano i tipi riferimenti creati con semantica dello stack.

Un motivo utilizzare gcnew (l'allocazione dinamica) anziché la semantica dello stack sarebbe se il tipo non ha un distruttore.Inoltre, utilizzando tipi di riferimenti creati con semantica dello stack in firme della funzione non sia possibile se si desidera che le funzioni da utilizzare con i linguaggi diversi da Visual C++.

Il compilatore non genererà un costruttore di copia per un tipo di riferimento.Pertanto, se si definisce una funzione che utilizza un tipo riferimento per valori nella firma, è necessario definire un costruttore di copia per il tipo di riferimento.Un costruttore di copia per un tipo di riferimento ha una firma di formato seguente: R(R%){}.

Il compilatore non genererà un operatore di assegnazione predefinito per un tipo di riferimento.Un operatore di assegnazione consente di creare un oggetto mediante la semantica dello stack e lo inizializzare con un oggetto esistente creato mediante la semantica dello stack.Un operatore di assegnazione per un tipo di riferimento ha una firma di formato seguente: void operator=( R% ){}){}.

Se le risorse critiche e si delle versioni del distruttore del tipo utilizzare la semantica dello stack per i tipi di riferimento, non è necessario chiamare in modo esplicito il distruttore (o chiamare delete).Per ulteriori informazioni sui distruttori nei tipi di riferimento, vedere Distruttori e finalizzatori in Visual C++.

Un operatore di assegnazione generato dal compilatore seguirà le normali regole standard C++ con le seguenti modifiche:

  • Tutti i membri dati non statico di tipo è un handle a un tipo di riferimento verranno copiati in apparenza (considerato come un membro dati non statico di tipo è un puntatore).

  • Qualsiasi membro dati non statico di tipo è un tipo di valore verrà copiato in apparenza.

  • Qualsiasi membro dati non statico di tipo è un'istanza di un tipo di riferimento richiamerà una chiamata al costruttore di copia di tipo riferimento.

Il compilatore fornisce inoltre un operatore unario di % per convertire un'istanza di un tipo di riferimento creato mediante la semantica dello stack nel tipo sottostante di handle.

I seguenti tipi di riferimenti non sono disponibili per l'utilizzo con semantica dello stack:

Esempio

ms177191.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio di codice seguente viene illustrato come dichiarare le istanze dei tipi di riferimento con semantica dello stack, il funzionamento del costruttore di copia e dell'operatore di assegnazione e come inizializzare un riferimento di rilevamento con tipo di riferimento creato utilizzando semantica dello stack.

ms177191.collapse_all(it-it,VS.110).gifCodice

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

ms177191.collapse_all(it-it,VS.110).gifOutput

98
98
98
13
13

Vedere anche

Riferimenti

Classi e struct (Estensioni del componente C++)