Semantyka stosu języka C++ dla typów odwołańC++ Stack Semantics for Reference Types

W starszych wersjach programu Visual Studio 2005 wystąpienie typu referencyjnego można utworzyć tylko przy użyciu new operatora, który utworzył obiekt na stertie zebranych elementów bezużytecznych.Prior to Visual Studio 2005, an instance of a reference type could only be created using the new operator, which created the object on the garbage collected heap. Można jednak teraz utworzyć wystąpienie typu referencyjnego przy użyciu tej samej składni, która będzie używana do tworzenia wystąpienia typu natywnego na stosie.However, you can now create an instance of a reference type using the same syntax that you would use to create an instance of a native type on the stack. Dlatego nie trzeba używać ref new, gcnew do tworzenia obiektu typu referencyjnego.So, you do not need to use ref new, gcnew to create an object of a reference type. A gdy obiekt wykracza poza zakres, kompilator wywołuje destruktor obiektu.And when the object goes out of scope, the compiler calls the object's destructor.

UwagiRemarks

Podczas tworzenia wystąpienia typu odwołania przy użyciu semantyki stosu kompilator wykonuje wewnętrznie Tworzenie wystąpienia na stosie odzyskiwanych elementów bezużytecznych (przy użyciu gcnew ).When you create an instance of a reference type using stack semantics, the compiler does internally create the instance on the garbage collected heap (using gcnew).

Gdy sygnatura lub typ zwracany funkcji zawiera wystąpienie typu odwołania przez wartość, funkcja zostanie oznaczona w metadanych jako wymagającej specjalnej obsługi (z modreq).When the signature or return type of a function includes an instance of a by-value reference type, the function will be marked in the metadata as requiring special handling (with modreq). Ta specjalna obsługa jest obecnie świadczona tylko przez Visual C++ klientów; inne języki nie obsługują obecnie korzystania z funkcji ani danych, które używają typów referencyjnych utworzonych przy użyciu semantyki stosu.This special handling is currently only provided by Visual C++ clients; other languages do not currently support consuming functions or data that use reference types created with stack semantics.

Jedną z przyczyn użycia gcnew (Alokacja dynamiczna) zamiast semantyki stosu będzie, jeśli typ nie ma destruktora.One reason to use gcnew (dynamic allocation) instead of stack semantics would be if the type has no destructor. Ponadto używanie typów odwołań utworzonych z semantyką stosu w sygnaturach funkcji nie będzie możliwe, jeśli chcesz, aby funkcje były używane przez języki inne niż Visual C++.Also, using reference types created with stack semantics in function signatures would not be possible if you want your functions to be consumed by languages other than Visual C++.

Kompilator nie będzie generował konstruktora kopiującego dla typu referencyjnego.The compiler will not generate a copy constructor for a reference type. W związku z tym, jeśli zdefiniujesz funkcję, która używa typu odwołania przez wartość w podpisie, musisz zdefiniować Konstruktor kopiujący dla typu referencyjnego.Therefore, if you define a function that uses a by-value reference type in the signature, you must define a copy constructor for the reference type. Konstruktor kopiujący dla typu referencyjnego ma podpis w następującej postaci: R(R%){} .A copy constructor for a reference type has a signature of the following form: R(R%){}.

Kompilator nie będzie generował domyślnego operatora przypisania dla typu referencyjnego.The compiler will not generate a default assignment operator for a reference type. Operator przypisania umożliwia utworzenie obiektu przy użyciu semantyki stosu i zainicjowanie go z istniejącym obiektem utworzonym przy użyciu semantyki stosu.An assignment operator allows you to create an object using stack semantics and initialize it with an existing object created using stack semantics. Operator przypisania dla typu referencyjnego ma sygnaturę następującej formy: void operator=( R% ){} .An assignment operator for a reference type has a signature of the following form: void operator=( R% ){}.

Jeśli destruktor typu zwalnia zasoby krytyczne i używasz semantyki stosu dla typów referencyjnych, nie musisz jawnie wywołać destruktora (lub wywołaniu delete ).If your type's destructor releases critical resources and you use stack semantics for reference types, you do not need to explicitly call the destructor (or call delete). Aby uzyskać więcej informacji na temat destruktorów w typach referencyjnych, zobacz destruktory i finalizatory w instrukcje: Definiowanie i korzystanie z klas i struktur (C++/CLI).For more information on destructors in reference types, see Destructors and finalizers in How to: Define and consume classes and structs (C++/CLI).

Generowany przez kompilator operator przypisania będzie przestrzegać zwykłych standardowych reguł języka C++ z następującymi dodatkami:A compiler-generated assignment operator will follow the usual standard C++ rules with the following additions:

  • Wszystkie niestatyczne składowe danych, których typ to dojście do typu referencyjnego, zostaną skopiowane na płytki (traktowane jak niestatyczny element członkowski danych, którego typem jest wskaźnik).Any non-static data members whose type is a handle to a reference type will be shallow copied (treated like a non-static data member whose type is a pointer).

  • Wszystkie niestatyczne składowe danych, których typem jest typ wartości, zostaną skopiowane na płytki.Any non-static data member whose type is a value type will be shallow copied.

  • Każdy niestatyczny element członkowski danych, którego typem jest wystąpienie typu referencyjnego, wywoła wywołanie konstruktora kopiującego typu odwołania.Any non-static data member whose type is an instance of a reference type will invoke a call to the reference type’s copy constructor.

Kompilator udostępnia również % operator jednoargumentowy do konwersji wystąpienia typu odwołania utworzonego przy użyciu semantyki stosu do jego bazowego typu uchwytu.The compiler also provides a % unary operator to convert an instance of a reference type created using stack semantics to its underlying handle type.

Następujące typy referencyjne nie są dostępne do użycia z semantyką stosu:The following reference types are not available for use with stack semantics:

PrzykładExample

OpisDescription

Poniższy przykład kodu pokazuje, jak zadeklarować wystąpienia typów odwołań z semantyką stosu, jak działa operator przypisania i Konstruktor kopiujący oraz jak zainicjować odwołanie śledzenia z typem referencyjnym utworzonym przy użyciu semantyki stosu.The following code sample shows how to declare instances of reference types with stack semantics, how the assignment operator and copy constructor works, and how to initialize a tracking reference with reference type created using stack semantics.

KodCode

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

Dane wyjścioweOutput

98
98
98
13
13

Zobacz teżSee also

Klasy i strukturyClasses and Structs