หมายเลขอ้างอิงใน C ++ คืออะไร?


98

ฉันได้รับแจ้งว่าแฮนเดิลเป็นประเภทของตัวชี้ แต่ไม่ใช่และช่วยให้คุณสามารถอ้างอิงถึงอ็อบเจ็กต์แทนที่จะเป็นอ็อบเจ็กต์เอง คำอธิบายที่ละเอียดกว่านี้คืออะไร?



2
เมื่อมองเข้าไปในรูปแบบ Chain of Responsibility คุณจะได้เรียนรู้ว่า "Handle" นั้นเป็นโหนดโดยพื้นฐานและ "Handler" เป็นชุดเล็ก ๆ "มายากล" มาจากการเรียกซ้ำ

คำตอบ:


101

จุดจับสามารถเป็นอะไรก็ได้ตั้งแต่ดัชนีจำนวนเต็มไปจนถึงตัวชี้ไปยังทรัพยากรในพื้นที่เคอร์เนล แนวคิดก็คือพวกเขาให้ทรัพยากรที่เป็นนามธรรมดังนั้นคุณไม่จำเป็นต้องรู้มากเกี่ยวกับทรัพยากรที่จะใช้มัน

ตัวอย่างเช่น HWND ใน Win32 API เป็นตัวจัดการสำหรับ Window โดยตัวมันเองไม่มีประโยชน์: คุณไม่สามารถรวบรวมข้อมูลใด ๆ จากมันได้ แต่ส่งต่อไปยังฟังก์ชัน API ที่เหมาะสมและคุณสามารถใช้กลเม็ดต่างๆมากมาย ภายในคุณสามารถคิดว่า HWND เป็นเพียงดัชนีในตารางหน้าต่างของ GUI (ซึ่งอาจไม่จำเป็นต้องเป็นวิธีการใช้งาน แต่มันทำให้เวทมนตร์มีความหมาย)

แก้ไข: ไม่แน่ใจ 100% ว่าคุณถามอะไรเป็นพิเศษในคำถามของคุณ นี่คือการพูดถึง C / C ++ บริสุทธิ์เป็นหลัก


14
Handle จะมีประโยชน์สำหรับการบันทึกสถานะ (อื่น ๆ ) หากคุณมีข้อมูลในโครงสร้างเช่น std :: vector วัตถุของคุณอาจอยู่ในตำแหน่งหน่วยความจำที่ต่างกันในช่วงเวลาที่ต่างกันระหว่างการทำงานของโปรแกรมซึ่งหมายความว่าตัวชี้ของคุณไปยังหน่วยความจำนั้นจะเปลี่ยนค่า ด้วยการจัดการที่ไม่เคยเปลี่ยนแปลงมันจะอ้างอิงวัตถุของคุณเสมอ ลองนึกภาพการบันทึกสถานะของโปรแกรม (เช่นในเกม) - คุณจะไม่บันทึกตำแหน่งตัวชี้ลงในข้อมูลและนำเข้าข้อมูลอีกครั้งในภายหลังและพยายามรับที่อยู่นั้นในหน่วยความจำ อย่างไรก็ตามคุณสามารถบันทึกจัดการกับข้อมูลของคุณและนำเข้าข้อมูลและจัดการได้
SinisterRainbow

เป็นไปได้ไหมที่จะแปลง HANDLE ให้เทียบเท่าใน Linux? ฉันต้องย้ายโปรแกรมที่ใช้ HANDLE จาก Windows ไปยัง Linux
Cornel Verster

1
นั่นคือคำตอบที่ถูกต้องซึ่งอาจเป็นอะไรก็ได้และรหัสที่ใช้กำหนดประเภทของแฮนเดิล ฉันพยายามสร้างคำตอบที่คล้ายกันของตัวเองให้กระชับมากขึ้นช่วยตัวเองไม่ได้สำหรับคนรุ่นหลัง @CornelVerster - เหมือนกันใน linux ฉันหมายถึงไม่ใช่ OS ที่จัดการ แต่เป็นแนวคิด ดังนั้นจึงขึ้นอยู่กับหมายเลขอ้างอิงเกี่ยวกับการโยกย้ายหรือแม้แต่จำเป็นต้องโยกย้าย
dyasta

@Matthew Iselin: ในเอกสาร API ใด ๆ พวกเขากำหนดว่าสิ่งนั้นเป็นตัวจัดการหรือไม่เราควรรู้ว่าจะส่งผ่านไปยังฟังก์ชันหรือไม่เราจะรู้ได้อย่างไรว่าอะไรคือตัวจัดการในเอกสาร API
Amin Khormaei

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 จะดูแลพวกเขา นอกจากนี้ GC ยังมีอิสระในการย้ายวัตถุบนฮีปที่มีการจัดการและอัปเดตแฮนเดิลให้ชี้ไปยังตำแหน่งใหม่ในขณะที่โปรแกรมกำลังทำงาน


5

สิ่งนี้ปรากฏในบริบทของHandle-Body-Idiomหรือที่เรียกว่า Pimpl idiom ช่วยให้สามารถเก็บ ABI (ไบนารีอินเทอร์เฟซ) ของไลบรารีไว้เหมือนเดิมโดยเก็บข้อมูลจริงไว้ในคลาสออบเจ็กต์อื่นซึ่งอ้างอิงโดยตัวชี้ที่อยู่ในอ็อบเจ็กต์ "ที่จับ" ซึ่งประกอบด้วยฟังก์ชันที่มอบหมายให้คลาสนั้น " ร่างกาย".

นอกจากนี้ยังมีประโยชน์ในการเปิดใช้งานเวลาคงที่และการแลกเปลี่ยนวัตถุสองอย่างที่ปลอดภัย ในการนี้จะต้องสลับตัวชี้ที่ชี้ไปยังวัตถุของร่างกายเท่านั้น


2

ที่จับคือสิ่งที่คุณต้องการให้เป็น

หมายเลขอ้างอิงสามารถเป็นจำนวนเต็มที่ไม่ได้ลงชื่อซึ่งใช้ในตารางการค้นหาบางตาราง

แฮนเดิลสามารถเป็นตัวชี้หรือเข้าไปในชุดข้อมูลขนาดใหญ่ได้

ขึ้นอยู่กับว่าโค้ดที่ใช้แฮนเดิลทำงานอย่างไร ที่กำหนดประเภทการจัดการ

เหตุผลที่ใช้คำว่า "ที่จับ " คือสิ่งที่สำคัญ ซึ่งบ่งชี้ว่าเป็นประเภทการระบุหรือการเข้าถึงของวัตถุ ความหมายสำหรับโปรแกรมเมอร์พวกเขาแสดงถึง 'คีย์' หรือการเข้าถึงบางสิ่ง


2

HANDLE hnd; เหมือนกับ void * ptr;

HANDLE เป็น typedef ที่กำหนดไว้ในไฟล์ winnt.h ใน Visual Studio (Windows):

typedef void *HANDLE;

อ่านเพิ่มเติมเกี่ยวกับHANDLE


1
ซึ่งใช้ได้กับ Windows เท่านั้นและมีเพียงแฮนเดิลประเภทเดียวที่ใช้ผ่านสถาปัตยกรรม Windows อย่างไรก็ตามนั่นคือสิ่งที่เรียกว่า 'ตัวจัดการระดับแอปพลิเคชัน Windows ปกติ'
dyasta
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.