Apa pegangan di C ++?

97

Saya telah diberitahu bahwa pegangan adalah semacam penunjuk, tetapi tidak, dan itu memungkinkan Anda untuk menyimpan referensi ke suatu objek, daripada objek itu sendiri. Apa penjelasan yang lebih rumit?

Xenoprimate
sumber
2
Perhatikan pola Rantai Tanggung Jawab, Anda akan belajar bahwa "Pegangan" pada dasarnya adalah sebuah simpul, dan bahwa "Penangan" adalah sekumpulan kecil dari mereka. "Ajaib" berasal dari rekursi

Jawaban:

100

Pegangan dapat berupa apa saja mulai dari indeks integer hingga penunjuk ke sumber daya dalam ruang kernel. Idenya adalah bahwa mereka menyediakan abstraksi sumber daya, jadi Anda tidak perlu tahu banyak tentang sumber daya itu sendiri untuk menggunakannya.

Misalnya, HWND di Win32 API adalah pegangan untuk Window. Dengan sendirinya itu tidak berguna: Anda tidak dapat mengumpulkan informasi apa pun darinya. Namun teruskan ke fungsi API yang tepat, dan Anda dapat melakukan banyak trik berbeda dengannya. Secara internal, Anda dapat menganggap HWND hanya sebagai indeks ke dalam tabel jendela GUI (yang mungkin belum tentu cara implementasinya, tetapi membuat keajaibannya masuk akal).

EDIT: Tidak 100% yakin apa yang secara khusus Anda tanyakan dalam pertanyaan Anda. Ini terutama berbicara tentang C / C ++ murni.

Matthew Iselin
sumber
13
Pegangan A dapat berguna untuk menyimpan status (antara lain). If u memiliki data dalam struktur seperti std :: vector. Objek Anda mungkin berada di lokasi memori yang berbeda pada waktu yang berbeda selama eksekusi program, yang berarti penunjuk Anda ke memori tersebut akan mengubah nilai. Dengan pegangan itu tidak pernah berubah, itu selalu mereferensikan objek Anda. Bayangkan menyimpan status program (seperti dalam permainan) - Anda tidak akan menyimpan lokasi penunjuk ke data dan kemudian mengimpor data lagi dan mencoba untuk mendapatkan alamat itu di memori. Namun Anda dapat menyimpan Handle dengan data Anda, dan mengimpor data dan handle.
SinisterRainbow
Apakah mungkin untuk mengubah HANDLE menjadi setara di Linux? Saya harus memigrasi program yang menggunakan HANDLE dari Windows ke Linux.
Cornel Verster
1
Itu adalah jawaban yang benar, bahwa mereka bisa apa saja, dan bahwa kode yang menggunakannya mendefinisikan jenis pegangan. Saya mencoba membuat versi yang lebih ringkas dari jawaban saya yang serupa, tidak dapat menahan diri, untuk anak cucu. @ CornelVerster - Mereka sama di linux. Maksud saya, bukan pegangan OS, tetapi konsepnya. Jadi, itu tergantung pada pegangan untuk migrasi, atau bahkan perlu bermigrasi.
dyasta
@Matthew Iselin: dalam dokumentasi API apa pun, apakah mereka mendefinisikan hal itu sebagai penangan maka kita harus tahu untuk meneruskannya ke fungsi, jika tidak, bagaimana kita dapat mengetahui apa itu penangan dalam dokumentasi API
Amin Khormaei
51

Pegangan adalah penunjuk atau indeks tanpa tipe yang terlihat terpasang padanya. Biasanya Anda melihat sesuatu seperti:

 typedef void* HANDLE;
 HANDLE myHandleToSomething = CreateSomething();

Jadi dalam kode Anda, Anda hanya meneruskan HANDLE sebagai nilai buram.

Dalam kode yang menggunakan objek, itu mentransmisikan penunjuk ke tipe struktur nyata dan menggunakannya:

 int doSomething(HANDLE s, int a, int b) {
     Something* something = reinterpret_cast<Something*>(s);
     return something->doit(a, b);
 }

Atau menggunakannya sebagai indeks ke array / vektor:

 int doSomething(HANDLE s, int a, int b) {
     int index = (int)s;
     try {
         Something& something = vecSomething[index];
         return something.doit(a, b);
     } catch (boundscheck& e) {
         throw SomethingException(INVALID_HANDLE);
     }
 }
jmucchiello.dll
sumber
29

Pegangan adalah semacam penunjuk yang biasanya merupakan cara mereferensikan beberapa entitas.

Akan lebih akurat untuk mengatakan bahwa penunjuk adalah salah satu jenis pegangan, tetapi tidak semua pegangan adalah penunjuk.

Misalnya, pegangan juga dapat berupa indeks ke dalam tabel dalam memori, yang terkait dengan entri yang berisi penunjuk ke beberapa objek.

Kuncinya adalah bahwa ketika Anda memiliki "pegangan", Anda tidak tahu atau peduli bagaimana pegangan itu benar-benar mengidentifikasi hal yang diidentifikasinya, yang perlu Anda ketahui adalah bahwa pegangan itu ada.

Juga harus jelas bahwa tidak ada jawaban tunggal untuk "apa sebenarnya pegangan", karena menangani hal-hal yang berbeda, bahkan dalam sistem yang sama, dapat diimplementasikan dengan cara yang berbeda "di bawah tenda". Tetapi Anda tidak perlu khawatir dengan perbedaan itu.

Deltics
sumber
6

Di C ++ / CLI, pegangan adalah penunjuk ke objek yang terletak di heap GC. Membuat objek pada heap C ++ (tidak dikelola) dilakukan dengan menggunakan newdan hasil newekspresi adalah pointer "normal". Objek terkelola dialokasikan di heap GC (terkelola) dengan gcnewekspresi. Hasilnya akan menjadi pegangan. Anda tidak dapat melakukan aritmatika penunjuk pada pegangan. Anda tidak melepaskan pegangan. GC akan mengurusnya. Selain itu, GC bebas untuk merelokasi objek di heap terkelola dan memperbarui pegangan untuk menunjuk ke lokasi baru saat program berjalan.

Mehrdad Afshari
sumber
5

Ini muncul dalam konteks Handle-Body-Idiom , juga disebut idiom Pimpl. Ini memungkinkan seseorang untuk menjaga ABI (antarmuka biner) pustaka yang sama, dengan menyimpan data aktual ke dalam objek kelas lain, yang hanya direferensikan oleh pointer yang disimpan dalam objek "pegangan", yang terdiri dari fungsi yang didelegasikan ke kelas itu " Tubuh".

Ini juga berguna untuk mengaktifkan waktu konstan dan pengecualian safe swap dari dua objek. Untuk ini, hanya penunjuk yang menunjuk ke objek tubuh yang harus ditukar.

Johannes Schaub - litb
sumber
2

Pegangan adalah apa pun yang Anda inginkan.

Sebuah pegangan bisa berupa integer tak bertanda tangan yang digunakan dalam beberapa tabel pencarian.

Pegangan bisa menjadi penunjuk ke, atau ke, kumpulan data yang lebih besar.

Itu tergantung pada bagaimana kode yang menggunakan pegangan berperilaku. Itu menentukan jenis pegangan.

Alasan istilah ' pegangan ' digunakan adalah yang terpenting. Itu menunjukkan mereka sebagai identifikasi atau tipe akses objek. Artinya, bagi programmer, mereka mewakili 'kunci' atau akses ke sesuatu.

dyasta.dll
sumber
2

HANDLE hnd; sama dengan void * ptr;

HANDLE adalah typedef yang ditentukan di file winnt.h di Visual Studio (Windows):

typedef void *HANDLE;

Baca lebih lanjut tentang HANDLE

Kulamani
sumber
1
Itu hanya berlaku untuk Windows, dan hanya satu dari banyak jenis pegangan yang digunakan melalui arsitektur Windows. Namun, itu adalah apa yang akan dikenal sebagai 'normal aplikasi Windows-tingkat pegangan'.
dyasta