Що таке ручка в C ++?


97

Мені сказали, що дескриптор - це свого роду вказівник, але ні, і що він дозволяє зберігати посилання на об’єкт, а не на сам об’єкт. Що є більш детальним поясненням?



2
Заглянувши в схему ланцюжка відповідальності, ви дізнаєтесь, що "ручка" - це в основному вузол, і що "обробник" - це невеликий набір з них. "

Відповіді:


100

Дескриптор може бути будь-яким - від цілочисельного індексу до вказівника на ресурс у просторі ядра. Ідея полягає в тому, що вони забезпечують абстракцію ресурсу, тому вам не потрібно знати багато про сам ресурс, щоб використовувати його.

Наприклад, HWND в Win32 API є дескриптором для вікна. Сам по собі він марний: ви не можете отримати з нього жодної інформації. Але передайте його правильним функціям API, і ви зможете виконати з ним безліч різноманітних трюків. Внутрішньо ви можете сприймати HWND як просто індекс в таблиці вікон графічного інтерфейсу (що не обов'язково може бути способом його реалізації, але магія має сенс).

РЕДАГУВАТИ: Не впевнений на 100%, що саме ви запитували у своєму питанні. В основному мова йде про чистий C / C ++.


13
Дескриптор може бути корисним для збереження станів (серед інших). Якщо u є дані в такій структурі, як std :: vector. Ваш об'єкт може знаходитися в різних місцях пам'яті в різний час під час виконання програми, що означає, що ваш вказівник на цю пам'ять змінить значення. За допомогою дескриптора він ніколи не змінюється, він завжди посилається на ваш об’єкт. Уявіть, як зберегти стан програми (як у грі) - ви не зберегли б розташування вказівника до даних, а згодом знову імпортували дані та спробували отримати цю адресу в пам’яті. Однак ви можете зберегти дескриптор із вашими даними та імпортувати дані та дескриптор.
SinisterRainbow

Чи можна перетворити HANDLE в еквівалент в Linux? Я повинен перенести програму, яка використовує HANDLE, з Windows на Linux.
Корнел Верстер

1
Це правильна відповідь, що вони можуть бути будь-якими, і що код, який їх використовує, визначає тип дескриптора. Я намагався зробити більш стислий варіант своєї власної подібної відповіді, не міг утриматися для нащадків. @CornelVerster - Вони однакові в Linux. Я маю на увазі не ручки ОС, а концепцію. Отже, це залежить від дескриптора щодо його міграції або навіть необхідності міграції.
діаста

@Matthew Iselin: в будь-якій документації API вони визначають, що річ є обробником, тоді ми повинні знати, як передавати їх функціям, інакше як ми можемо знати, що таке обробник в документації API
Амін Хормаї,

51

Дескриптор - це вказівник або індекс, до якого не прикріплений видимий тип. Зазвичай ви бачите щось на зразок:

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

Отже, у коді ви просто передаєте HANDLE навколо як непрозоре значення.

У коді, який використовує об'єкт, він передає покажчик на реальний тип структури і використовує його:

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

Або він використовує його як індекс масиву / вектора:

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

29

Дескриптор - це свого роду вказівник, оскільки він, як правило, є способом посилання на якусь сутність.

Точніше було б сказати, що покажчик - це один тип дескриптора, але не всі дескриптори є покажчиками.

Наприклад, дескриптор також може бути індексом таблиці в пам'яті, що відповідає запису, який сам містить вказівник на якийсь об'єкт.

Ключовим є те, що коли у вас є "ручка", ви ні знаєте, ні піклуєтесь, як ця ручка насправді виявляє ідентифікацію речі, яку вона ідентифікує, все, що вам потрібно знати, це те, що вона робить.

Також повинно бути очевидно, що немає однозначної відповіді на те, "що саме являє собою ручка", оскільки ручки до різних речей, навіть в одній і тій же системі, можуть бути реалізовані по-різному "під капотом". Але вам не слід турбуватися про ці відмінності.


6

У C ++ / CLI дескриптор - це вказівник на об'єкт, розташований у купі GC. Створення об'єкта на (некерованій) купі C ++ досягається за допомогою, newа результатом newвиразу є "звичайний" покажчик. Керований об'єкт виділяється на купі GC (керований) із gcnewвиразом. Результатом буде ручка. Ви не можете робити арифметику покажчиків на ручках. Ви не звільняєте ручки. ГК подбає про них. Крім того, GC може вільно переміщувати об'єкти в керованій купі та оновлювати дескриптори, щоб вказувати на нові місця, поки програма працює.


5

Це з’являється в контексті ідіоми Handle-Body-Idiom , яку також називають ідіомою Pimpl. Це дозволяє зберегти ABI (двійковий інтерфейс) бібліотеки однаковим, зберігаючи фактичні дані в іншому об'єкті класу, на який просто посилається вказівник, що міститься в об'єкті "handle", що складається з функцій, які делегують цьому класу " Тіло ».

Корисно також увімкнути постійний обмін двома об’єктами за часом та виключеннями. Для цього потрібно просто поміняти місцями лише вказівник, що вказує на об’єкт body.


2

Ручка - це все, що ти хочеш.

Ручкою може бути ціле число без підпису, яке використовується в деякій таблиці пошуку.

Ручка може бути вказівником на більший набір даних або на них.

Це залежить від того, як поводиться код, який використовує дескриптор. Це визначає тип ручки.

Причиною використання терміна " ручка " є те, що важливо. Це вказує на них як на ідентифікаційний об'єкт або тип доступу. Це означає, що для програміста вони представляють "ключ" або доступ до чогось.


2

HANDLE hnd; те саме, що void * ptr;

HANDLE - це typedef, визначений у файлі winnt.h у Visual Studio (Windows):

typedef void *HANDLE;

Детальніше про HANDLE


1
Це стосується лише Windows і лише одного з багатьох типів ручок, що використовуються в архітектурі Windows. Однак це те, що називають "звичайним дескриптором рівня програми Windows".
дьяста
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.