เหตุใดจึงมีชื่อชั้นฉีด


147

เมื่อเร็ว ๆ นี้ผมเห็นคุณลักษณะ C ++ แปลก: ฉีดชื่อชั้น

class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...

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

และฉันได้ยินว่าคุณสมบัตินี้ไม่มีอยู่ใน C ++ เก่า จากนั้นเมื่อไหร่ที่มันถูกนำมาใช้? C ++ 03? C ++ 11?


บัดดี้คุณสามารถดู Skype ได้ไหม? ฉันไม่สามารถติดต่อคุณได้
Irinel Iovan

คำตอบ:


162

ชื่อคลาสที่ถูกฉีดหมายความว่าXประกาศให้เป็นสมาชิกXดังนั้นการค้นหาชื่อภายในXจะค้นหาคลาสปัจจุบันเสมอไม่ใช่ชื่ออื่นXที่อาจถูกประกาศในขอบเขตการล้อมรอบเดียวกันเช่น

void X() { }
class X {
public:
  static X create() { return X(); }
};

เป็นcreate()ฟังก์ชั่นการสร้างชั่วคราวXวัตถุหรือเรียกฟังก์ชั่นX? ที่ขอบเขตเนมสเปซจะเรียกใช้ฟังก์ชันดังนั้นจุดประสงค์ของชื่อคลาสที่ถูกแทรกคือเพื่อให้แน่ใจว่าภายในเนื้อความของXชื่อจะค้นหาคลาสเองเสมอ (เนื่องจากการค้นหาชื่อเริ่มต้นในขอบเขตของคลาสก่อนที่จะมองหาสิ่งที่แนบ ขอบเขต).

นอกจากนี้ยังมีประโยชน์ในเทมเพลตของชั้นเรียนซึ่งสามารถใช้ชื่อคลาสที่ฉีดได้โดยไม่มีรายการอาร์กิวเมนต์เทมเพลตเช่นใช้Fooแทนเท็มเพลตไอดีแบบเต็มFoo<blah, blah, blah>ดังนั้นจึงง่ายต่อการอ้างถึงอินสแตนซ์ปัจจุบัน ดูDR 176สำหรับการเปลี่ยนแปลงระหว่าง C ++ 98 และ C ++ 03 ที่ทำให้ชัดเจน

แนวคิดของชื่อคลาสที่ถูกฉีดนั้นมีอยู่ใน C ++ 98 แต่คำศัพท์นั้นใหม่สำหรับ C ++ 03

C ++ 98 พูดว่า:

ชื่อชั้นถูกแทรกเข้าไปในขอบเขตในการที่จะมีการประกาศทันทีหลังจากที่ชื่อชั้นจะเห็น ชื่อคลาสจะถูกแทรกลงในขอบเขตของคลาสเองด้วย

ประโยคที่สองถูกเปลี่ยนแปลงโดยDR 147ดังนั้น C ++ 03 พูดว่าใน [class] / 2:

ชื่อชั้นถูกแทรกเข้าไปในขอบเขตในการที่จะมีการประกาศทันทีหลังจากที่ชื่อชั้นจะเห็น ชื่อชั้นยังเป็นที่ใส่เข้าไปในขอบเขตของชั้นเองนั้น นี้เป็นที่รู้จักกันฉีดชั้นชื่อ

ก่อนถึง C ++ 98 ARM มีถ้อยคำที่เทียบเท่ากันโดยคร่าวๆซึ่งหมายความว่าชื่อคลาสสามารถใช้ในคลาสของร่างกายเพื่ออ้างถึงคลาสได้:

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

  • ตัวอย่างเช่น,

    class link { link* next; };


2
ฉันถูกถามว่าค่อนข้างบ่อย แต่ไม่สามารถสร้างตัวอย่างง่ายๆที่ชี้ให้เห็นปัญหาได้ ดังนั้น +1 สำหรับตัวอย่าง
dhein

1
สิ่งนี้สามารถมองเห็นได้อย่างชัดเจนถ้าคุณเรียกใช้ clang ++ your_program.cpp -Xclang -ast-dump และคุณเห็นคลาสของคุณจากนั้นโหนดโหนดลูกระดับที่ถูกฉีด
xaxxon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.