Bagikan melalui


C++ Stack Semantics untuk Jenis Referensi

Sebelum Visual Studio 2005, instans jenis referensi hanya dapat dibuat menggunakan new operator, yang membuat objek pada tumpukan yang dikumpulkan sampah. Namun, Anda sekarang dapat membuat instans jenis referensi menggunakan sintaks yang sama dengan yang akan Anda gunakan untuk membuat instans jenis asli pada tumpukan. Jadi, Anda tidak perlu menggunakan ref baru, gcnew untuk membuat objek jenis referensi. Dan ketika objek keluar dari cakupan, pengkompilasi memanggil destruktor objek.

Keterangan

Saat Anda membuat instans jenis referensi menggunakan semantik tumpukan, pengkompilasi membuat instans secara internal pada tumpukan yang dikumpulkan sampah (menggunakan gcnew).

Ketika tanda tangan atau jenis pengembalian fungsi menyertakan instans jenis referensi berdasarkan nilai, fungsi akan ditandai dalam metadata sebagai memerlukan penanganan khusus (dengan modreq). Penanganan khusus ini saat ini hanya disediakan oleh klien Visual C++; bahasa lain saat ini tidak mendukung penggunaan fungsi atau data yang menggunakan jenis referensi yang dibuat dengan semantik tumpukan.

Salah satu alasan untuk menggunakan gcnew (alokasi dinamis) alih-alih semantik tumpukan adalah jika jenis tidak memiliki destruktor. Selain itu, menggunakan jenis referensi yang dibuat dengan semantik tumpukan dalam tanda tangan fungsi tidak akan dimungkinkan jika Anda ingin fungsi Anda dikonsumsi oleh bahasa selain Visual C++.

Pengkompilasi tidak akan menghasilkan konstruktor salinan untuk jenis referensi. Oleh karena itu, jika Anda menentukan fungsi yang menggunakan jenis referensi menurut nilai dalam tanda tangan, Anda harus menentukan konstruktor salinan untuk jenis referensi. Konstruktor salinan untuk jenis referensi memiliki tanda tangan formulir berikut: R(R%){}.

Pengkompilasi tidak akan menghasilkan operator penugasan default untuk jenis referensi. Operator penugasan memungkinkan Anda membuat objek menggunakan semantik tumpukan dan menginisialisasinya dengan objek yang ada yang dibuat menggunakan semantik tumpukan. Operator penugasan untuk jenis referensi memiliki tanda tangan formulir berikut: void operator=( R% ){}.

Jika destruktor jenis Anda merilis sumber daya penting dan Anda menggunakan semantik tumpukan untuk jenis referensi, Anda tidak perlu secara eksplisit memanggil destruktor (atau memanggil delete). Untuk informasi selengkapnya tentang destruktor dalam jenis referensi, lihat Destruktor dan finalizer dalam Cara: Menentukan dan menggunakan kelas dan struktur (C++/CLI).

Operator penugasan yang dihasilkan kompilator akan mengikuti aturan C++ standar biasa dengan penambahan berikut:

  • Setiap anggota data non-statis yang jenisnya adalah handel ke jenis referensi akan disalin dangkal (diperlakukan seperti anggota data non-statis yang jenisnya adalah penunjuk).

  • Setiap anggota data non-statis yang jenisnya adalah jenis nilai akan disalin dangkal.

  • Setiap anggota data non-statis yang jenisnya adalah instans jenis referensi akan memanggil panggilan ke konstruktor salinan jenis referensi.

Pengkompilasi juga menyediakan % operator unary untuk mengonversi instans jenis referensi yang dibuat menggunakan semantik tumpukan ke jenis handel yang mendasarinya.

Jenis referensi berikut ini tidak tersedia untuk digunakan dengan semantik tumpukan:

Contoh

Deskripsi

Sampel kode berikut menunjukkan cara mendeklarasikan instans jenis referensi dengan semantik tumpukan, cara kerja operator penugasan dan konstruktor salin, dan cara menginisialisasi referensi pelacakan dengan jenis referensi yang dibuat menggunakan semantik tumpukan.

Kode

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

Hasil

98
98
98
13
13

Baca juga

Kelas dan Struktur