เหตุใดตัวชี้ 'this' จึงไม่ใช่ตัวอ้างอิง


183

ฉันกำลังอ่านคำตอบสำหรับคำถามนี้ข้อดีและข้อเสีย C ++และมีข้อสงสัยนี้ในขณะที่อ่านความคิดเห็น

โปรแกรมเมอร์มักพบว่าสับสนว่า "นี่" เป็นตัวชี้ แต่ไม่ใช่การอ้างอิง ความสับสนอีกอย่างคือทำไม "hello" ไม่ใช่ type std :: string แต่ประเมินเป็น char const * (ตัวชี้) (หลังจากการแปลงอาเรย์เป็นตัวชี้) - Johannes Schaub - litb 22 ธันวาคม 2008 เวลา 1:56

นั่นแสดงให้เห็นว่ามันไม่ได้ใช้แบบแผนเดียวกับภาษาอื่น ๆ (ในภายหลัง) - เลอ dorfier 22 ธันวาคม '08 ที่ 3:35

ฉันจะเรียกสิ่งนี้ว่า "ปัญหาเล็กน้อย" และอุ๊ปส์ขอบคุณสำหรับการจับข้อผิดพลาดเล็กน้อยในตัวอย่างของพฤติกรรมที่ไม่ได้กำหนด :) ถึงแม้ว่าฉันไม่เข้าใจว่าข้อมูลเกี่ยวกับขนาดเกี่ยวข้องกับอะไรในข้อมูลแรก ตัวชี้ไม่ได้รับอนุญาตให้ชี้ออกไปนอกหน่วยความจำที่จัดสรร - วันที่ 22 ธันวาคม 2551 เวลา 4:18 น

นี่เป็นพอยน์เตอร์คงที่หรือไม่? - yesraaj 22 ธันวาคม 2551 เวลา 6:35 น

สิ่งนี้จะคงที่หากวิธีการนั้นเป็น const int getFoo () const; <- ในขอบเขตของ getFoo "this" เป็นค่าคงที่และอ่านได้อย่างเดียว สิ่งนี้จะป้องกันข้อผิดพลาดและให้การรับประกันระดับหนึ่งแก่ผู้เรียกที่วัตถุจะไม่เปลี่ยนแปลง - Doug T. 22 ธ.ค. 2551 เวลา 16:42 น

คุณไม่สามารถกำหนด "สิ่งนี้" ใหม่ได้ นั่นคือคุณไม่สามารถทำ "this = & other;" เพราะนี่เป็นค่า rvalue แต่นี่เป็นประเภท T * ไม่ใช่ของประเภท T const นั่นคือมันเป็นตัวชี้ที่ไม่คงที่ หากคุณอยู่ในวิธีการ const แล้วมันเป็นตัวชี้ไปที่ const T const แต่ตัวชี้นั้นไม่เป็นที่นิยม - Johannes Schaub - litb 22 ธันวาคม 2008 เวลา 17:53 น

คิดว่า "นี่" เป็นอย่างนี้: #define this (this_ + 0) ที่คอมไพเลอร์สร้าง "this_" นี้เป็นตัวชี้ไปยังวัตถุและทำให้ "นี่" เป็นคำหลัก คุณไม่สามารถกำหนด "this" เพราะ (this_ + 0) เป็นค่า rvalue แน่นอนว่ามันไม่เป็นเช่นนั้น (ไม่มีมาโครดังกล่าว) แต่มันสามารถช่วยให้เข้าใจได้ - โยฮันเนส Schaub - litb 22 ธันวาคม 2551 เวลา 17:55 น.

คำถามของฉันคือเหตุใดthisตัวชี้จึงไม่ใช่ข้อมูลอ้างอิง มีเหตุผลใดที่ทำให้เป็นตัวชี้?


ข้อโต้แย้งเพิ่มเติมว่าทำไมthisการอ้างอิงถึงสมเหตุสมผล:

  • พิจารณาItem 1จากMore Effective C++ : ใช้การอ้างอิงเมื่อมันรับประกันว่าเรามีวัตถุที่ถูกต้องเช่นไม่ใช่ NULL (การตีความของฉัน)
  • นอกจากนี้การอ้างอิงถือว่าปลอดภัยกว่าพอยน์เตอร์ (เนื่องจากเราไม่สามารถไขหน่วยความจำด้วยพอยต์เรย์)
  • ประการที่สามไวยากรณ์สำหรับการเข้าถึงการอ้างอิง ( .) เล็กน้อยดีกว่าและสั้นกว่าการเข้าถึงตัวชี้ ( ->หรือ(*))

5
@paulm "แฮ็ค" นี้จะสำเร็จได้อย่างไร ไม่ได้thisประเมินเสมอไปtrueหรือ
iFreilicht

6
@paulm ฉันไม่คิดว่ามันใช้งานได้จริง C ++ การเรียกใช้เมธอด nullptr ไปยังวัตถุจะทำให้เกิดพฤติกรรมที่ไม่ได้กำหนด
antred

5
@ paulm อาจใช้งานได้ในบางกรณี แต่ลองคิดดูว่าวิธีการนั้นเป็นแบบ virutal หรือไม่ การค้นหา v-table สามารถทำได้โดยไม่มีวัตถุได้อย่างไร?
Jason Creighton

3
@ paulm หากคุณเห็นมันในรหัสการผลิตให้ละทิ้งเรือ! นั่นคือ UB
อลิซ

6
ฉันแค่จะออกจากที่นี่ ... (จาก afxwin2.inl ของ MFC):_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL : m_hWnd; }
Christopher Oicles

คำตอบ:


176

เมื่อภาษามีการพัฒนาเป็นครั้งแรกในช่วงต้นที่มีผู้ใช้จริงไม่มีการอ้างอิงมีเพียงพอยน์เตอร์ มีการเพิ่มการอ้างอิงเมื่อมีการเพิ่มตัวดำเนินการมากเกินไปเนื่องจากต้องการการอ้างอิงเพื่อทำงานอย่างสม่ำเสมอ

หนึ่งในการใช้งานของthisวัตถุที่จะได้รับตัวชี้ไปที่ตัวเอง &thisถ้ามันเป็นอ้างอิงแล้วเราจะต้องเขียน ในทางกลับกันเมื่อเราเขียนผู้ประกอบการที่ได้รับมอบหมายเราต้องซึ่งจะมีลักษณะที่เรียบง่ายเป็นreturn *this return thisดังนั้นหากคุณมีกระดานชนวนว่างเปล่าคุณสามารถโต้แย้งได้ทั้งสองวิธี แต่ C ++ จะค่อยๆพัฒนาเพื่อตอบรับข้อเสนอแนะจากชุมชนผู้ใช้ (เช่นสิ่งที่ประสบความสำเร็จมากที่สุด) คุณค่าของความเข้ากันได้แบบย้อนหลังนั้นทำให้เกิดข้อดีและข้อเสียเล็ก ๆ น้อย ๆ ที่เกิดจากthisการอ้างอิงหรือตัวชี้


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

20
และถ้านี่เป็นข้อมูลอ้างอิงมันจะยากเกินที่operator &จะทำสิ่งที่มีประโยชน์ operator &มีจะต้องมีไวยากรณ์พิเศษบางอย่างสำหรับการอยู่ของนี้ที่จะไม่ผ่านไป
Omnifarious

10
@conio - คุณอาจต้องการตรวจสอบว่าครั้งต่อไปที่คุณอยู่ใกล้คอมไพเลอร์ C ++! :) สิ่งที่ต้องการ:int n = 5; int &r = n; int *p = &r; std::cout << *p;
Daniel Earwicker

14
@ แตกต่างกันคุณสามารถเขียน&reinterpret_cast<char&>(this);เพื่อรับที่อยู่ที่แท้จริงสำหรับการบรรทุกเกินพิกัดoperator&(อันที่จริงนี่คือสิ่งที่boost::addressofจะทำ)
Johannes Schaub - litb

9
เนื่องจากมันไม่สมเหตุสมผลเลยที่thisจะเป็นโมฆะฉันคิดว่าการอ้างอิงนั้นเหมาะสมกว่าจริงๆ
Ponkadoodle

114

สายไปงานเลี้ยงเล็ก ๆ ... ตรงจากปากม้านี่คือสิ่งที่ Bjarne Stroustrup พูด (ซึ่งซ้ำไปซ้ำมาหรือนำมาจากหนังสือ "การออกแบบและวิวัฒนาการของ C ++"):

ทำไม " this" ไม่ใช่ข้อมูลอ้างอิง

เพราะ "สิ่งนี้" ถูกนำไปใช้กับ C ++ (จริงๆใน C กับคลาส) ก่อนที่จะมีการเพิ่มการอ้างอิง นอกจากนี้ฉันเลือก " this" เพื่อติดตามการใช้งาน Simula มากกว่าการใช้ "ตัวเอง" ของ Smalltalk


2
ใช่ตัวตนคงจะดีสำหรับความสอดคล้องกับภาษาอื่น ๆ ได้ดี
pilkch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.