Delen via


C++ Stack-semantiek voor verwijzingstypen

Vóór Visual Studio 2005 kon een instantie van een verwijzingstype alleen worden gemaakt met behulp van de new-operator, die het object op de afvalverzamelde heap creëerde. U kunt nu echter een exemplaar van een verwijzingstype maken met dezelfde syntaxis die u zou gebruiken om een exemplaar van een systeemeigen type op de stack te maken. U hoeft dus geen ref new te gebruiken , gcnew om een object van een verwijzingstype te maken. En wanneer het object buiten het bereik valt, roept de compiler de destructor van het object aan.

Opmerkingen

Wanneer u een exemplaar van een referentietype maakt met behulp van stack-semantiek, maakt de compiler intern het exemplaar op de garbage collected heap (met behulp van gcnew).

Wanneer de handtekening of het retourtype van een functie een exemplaar van een waarde-referentietype bevat, wordt de functie in de metagegevens gemarkeerd als vereisend speciale verwerking (met modreq). Deze speciale verwerking wordt momenteel alleen aangeboden door Visual C++ clients; andere talen bieden momenteel geen ondersteuning voor het gebruik van functies of gegevens die gebruikmaken van referentietypen die zijn gemaakt met stack-semantiek.

Een van de redenen om (dynamische toewijzing) te gebruiken gcnew in plaats van stack-semantiek, is als het type geen destructor heeft. Het gebruik van referentietypen die zijn gemaakt met stack-semantiek in functiehandtekeningen, is ook niet mogelijk als u wilt dat uw functies worden gebruikt door andere talen dan Visual C++.

De compiler genereert geen kopieerconstructor voor een referentietype. Als u daarom een functie definieert die gebruikmaakt van een referentietype dat waarden doorgeeft in de handtekening, moet u een kopieerconstructor definiëren voor het referentietype. Een kopieerconstructor voor een verwijzingstype heeft een handtekening in de volgende vorm: R(R%){}.

De compiler genereert geen standaardtoewijzingsoperator voor een referentietype. Met een toewijzingsoperator kunt u een object maken met behulp van stack-semantiek en het initialiseren met een bestaand object dat is gemaakt met behulp van stack-semantiek. Een toewijzingsoperator voor een verwijzingstype heeft een handtekening van de volgende vorm: void operator=( R% ){}.

Als de destructor van uw type kritieke resources vrijgeeft en u stack-semantiek gebruikt voor referentietypen, hoeft u de destructor (of delete aanroep) niet expliciet aan te roepen. Zie: voor meer informatie over destructors in referentietypen, Destructors en finalizers in How to: Define and consume classes and structs (C++/CLI).

Een door compiler gegenereerde toewijzingsoperator volgt de gebruikelijke standaard C++-regels met de volgende toevoegingen:

  • Niet-statische gegevensleden waarvan het type een ingang is voor een verwijzingstype, worden ondiep gekopieerd (behandeld als een niet-statisch gegevenslid waarvan het type een aanwijzer is).

  • Elk niet-statisch gegevenslid waarvan het type een waardetype is, wordt ondiep gekopieerd.

  • Elk niet-statisch gegevenslid waarvan het type een exemplaar van een verwijzingstype is, roept een aanroep aan naar de kopieerconstructor van het verwijzingstype.

De compiler biedt ook een % unaire operator voor het converteren van een exemplaar van een verwijzingstype dat is gemaakt met behulp van stack-semantiek naar het onderliggende handletype.

De volgende referentietypen zijn niet beschikbaar voor gebruik met stack-semantiek:

Voorbeeld

Beschrijving

In het volgende codevoorbeeld ziet u hoe u exemplaren van referentietypen declareert met stack-semantiek, hoe de toewijzingsoperator en kopieerconstructor werkt en hoe u een traceringsreferentie initialiseert met verwijzingstype dat is gemaakt met behulp van stack-semantiek.

Code

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

Uitvoer

98
98
98
13
13

Zie ook

Klassen en Structs