ความเหนือกว่าของเนมสเปซที่ไม่มีชื่อมากกว่าแบบคงที่?


130

เนมสเปซที่ไม่มีชื่อเหนือกว่าstaticคีย์เวิร์ดอย่างไร


อย่างไรก็ตามเนมสเปซที่ไม่มีชื่อไม่สามารถแทนที่เนมสเปซแบบคงที่ได้อย่างเพียงพอตามที่คณะกรรมการมาตรฐานกำหนด ยังมีบางกรณีที่เนมสเปซที่ไม่มีชื่อล้มเหลวและใช้staticงานได้เท่านั้น
legends2k

คำตอบ:


134

โดยทั่วไปคุณกำลังอ้างถึงส่วน§7.3.1.1 / 2 จากมาตรฐาน C ++ 03

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

โปรดทราบว่าย่อหน้านี้ถูกลบออกไปแล้วใน C ++ 11 staticฟังก์ชันเป็นไปตามมาตรฐานไม่เลิกใช้อีกต่อไป!

อย่างไรก็ตาม namespaces ไม่มีชื่อจะดีกว่าคำหลักที่คงที่ส่วนใหญ่เป็นเพราะคำที่staticใช้เฉพาะกับตัวแปรการประกาศและฟังก์ชั่นไม่ให้ผู้ใช้กำหนดประเภท

รหัสต่อไปนี้ใช้ได้ใน C ++

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

แต่รหัสนี้ไม่ถูกต้อง:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

วิธีแก้ปัญหาคือเนมสเปซที่ไม่มีชื่อซึ่งก็คือนี่

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

หวังว่ามันจะอธิบายว่าทำไมถึงunnamed-namespaceเหนือกว่าstatic.

นอกจากนี้โปรดทราบว่าการใช้คีย์เวิร์ดแบบคงที่จะเลิกใช้เมื่อประกาศอ็อบเจ็กต์ในขอบเขตเนมสเปซ (ตามมาตรฐาน)


11
โดยทั่วไปแล้วเนมสเปซที่ไม่มีชื่อจะอนุญาตให้เชื่อมโยงภายนอกได้ นั่นคือสิ่งที่เปิดใช้งานการประกาศคลาสหน่วยแปลเป็นภาษาท้องถิ่น นอกจากนี้ยังอนุญาตเช่นค่าคงที่สตริงการเชื่อมโยงภายนอกเพื่อใช้เป็นอาร์กิวเมนต์แม่แบบ
ไชโยและ hth - Alf

10
ตามที่ Fred Nurk ระบุไว้ในคำตอบอื่นของคุณดูเหมือนว่าdeprecatedคำพูดนี้จะถูกลบออกจาก C ++ 0x FCD ล่าสุด (n3225)
Matthieu M.

36
คุณกำลังตอบคำถามของคุณเองและกล่าวขอบคุณตัวเอง: -o
manpreet singh

12
อะไรคือความแตกต่างจากการกำหนดคลาสใน cpp (ไม่มีเนมสเปซที่ไม่ระบุตัวตน, ไม่มีสแตติก)?
Luchian Grigore

6
@LuchianGrigore ปัญหาการเชื่อมโยงในกรณีที่ 2 .cppกำลังกำหนดคลาสที่มีชื่อเดียวกัน
Xaqq

8

มีปัญหาที่น่าสนใจเกี่ยวกับสิ่งนี้:

สมมติว่าคุณใช้staticคำสำคัญหรือไม่มีชื่อnamespaceเพื่อทำให้ฟังก์ชันบางอย่างอยู่ภายในโมดูล (หน่วยการแปล) เนื่องจากฟังก์ชันนี้มีขึ้นเพื่อใช้ภายในโมดูลและไม่สามารถเข้าถึงได้จากภายนอก (ไม่มีชื่อnamespaces มีข้อได้เปรียบในการสร้างข้อมูลและคำจำกัดความประเภทภายในเช่นกันนอกเหนือจากฟังก์ชัน)

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

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

การไม่ตั้งชื่อnamespaceจะไม่สามารถแก้ปัญหานี้ได้เนื่องจากมีการกำหนดไว้สำหรับไฟล์ต้นฉบับเฉพาะ (หน่วยการแปล) และไม่สามารถเข้าถึงได้จากภายนอก

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


3
มันจะเป็นการแฮ็คและเป็นวิธีแก้ปัญหาที่ จำกัด แต่คุณสามารถรวมไฟล์ cpp ที่มีฟังก์ชันคงที่หรือเนมสเปซภายในไว้ในไฟล์ cpp 'หลัก' ของคุณ จากนั้นแยกไฟล์ cpp 'satellite' เหล่านี้ออกจากบิลด์และคุณทำเสร็จแล้ว ปัญหาเดียวถ้าคุณมีไฟล์ cpp 'หลัก' สองไฟล์ขึ้นไปและทั้งคู่ต้องการใช้ฟังก์ชันเจ๋ง ๆ จากไฟล์ cpp 'ดาวเทียม' ตัวใดตัวหนึ่ง ...
Sergey

ไม่ได้ใช้การสืบทอดกับไพรเวต / ป้องกัน / สาธารณะที่มีฟังก์ชันคงที่ใช่หรือไม่
อาลี

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