ขั้นแรกคำศัพท์บางคำ:
- ใช้ประกาศ :
using std::vector;
- การใช้คำสั่ง :
using namespace std;
ฉันคิดว่าการใช้คำสั่งการใช้งานนั้นใช้ได้ตราบใดที่ไม่ได้ใช้ในขอบเขตส่วนกลางในไฟล์ส่วนหัว ดังนั้นการมี
using namespace std;
ในไฟล์. cpp ของคุณไม่ใช่ปัญหาจริงๆและหากปรากฎว่าเป็นเช่นนั้นก็จะอยู่ภายใต้การควบคุมของคุณโดยสมบูรณ์ (และยังสามารถกำหนดขอบเขตไปยังบล็อกใดบล็อกหนึ่งได้หากต้องการ) ฉันไม่เห็นเหตุผลของอนุภาคที่จะทำให้โค้ดยุ่งเหยิงด้วยstd::
คุณสมบัติมากมาย - มันกลายเป็นสัญญาณรบกวนภาพมากมาย อย่างไรก็ตามหากคุณไม่ได้ใช้ชื่อทั้งหมดจากstd
เนมสเปซในโค้ดของคุณฉันก็ไม่เห็นปัญหาในการละทิ้งคำสั่ง มันเป็น tautology - หากไม่จำเป็นต้องใช้คำสั่งก็ไม่จำเป็นต้องใช้มัน
ในทำนองเดียวกันหากคุณสามารถทำได้โดยใช้การประกาศโดยใช้ไม่กี่คำ (แทนที่จะใช้คำสั่ง ) สำหรับประเภท specfic ในstd
เนมสเปซก็ไม่มีเหตุผลที่คุณไม่ควรมีเพียงชื่อเฉพาะที่นำเข้ามาในเนมสเปซปัจจุบัน ในทำนองเดียวกันฉันคิดว่ามันคงบ้าและการทำบัญชียุ่งยากที่จะต้องมีการประกาศการใช้ 25 หรือ 30 ครั้งเมื่อคำสั่งการใช้เดียวจะทำเคล็ดลับได้เช่นกัน
นอกจากนี้โปรดทราบว่ามีหลายครั้งที่คุณต้องใช้การประกาศใช้ อ้างถึง "รายการที่ 25 ของ Scott Meyers: พิจารณาการสนับสนุนสำหรับการแลกเปลี่ยนแบบไม่โยนทิ้ง" จาก C ++ ที่มีผลบังคับใช้รุ่นที่สาม เพื่อให้มีฟังก์ชันเทมเพลตทั่วไปใช้วิธีการสลับ 'ที่ดีที่สุด' สำหรับประเภทที่กำหนดพารามิเตอร์คุณต้องใช้ประโยชน์จากการประกาศโดยใช้และการค้นหาตามอาร์กิวเมนต์ (aka ADL หรือ Koenig lookup):
template< typename T >
void foo( T& x, T& y)
{
using std::swap; // makes std::swap available in this function
// do stuff...
swap( x, y); // will use a T-specific swap() if it exists,
// otherwise will use std::swap<T>()
// ...
}
ฉันคิดว่าเราควรดูสำนวนทั่วไปสำหรับภาษาต่างๆที่ใช้เนมสเปซอย่างมีนัยสำคัญ ตัวอย่างเช่น Java และ C # ใช้เนมสเปซในระดับมาก (เนื้อหามากกว่า C ++) วิธีที่ใช้บ่อยที่สุดชื่อภายในเนมสเปซในภาษาเหล่านั้นคือการนำชื่อเหล่านั้นเข้าสู่ขอบเขตปัจจุบันโดยรวมเทียบเท่ากับการใช้คำสั่ง สิ่งนี้ไม่ก่อให้เกิดปัญหาในวงกว้างและไม่กี่ครั้งที่เป็นปัญหาจะได้รับการจัดการบนพื้นฐาน 'ข้อยกเว้น' โดยจัดการกับชื่อที่เป็นปัญหาผ่านชื่อที่มีคุณสมบัติครบถ้วนหรือโดยการใช้นามแฝง - เช่นเดียวกับที่สามารถทำได้ใน C ++
Herb Sutter และ Andrei Alexandrescu กล่าวไว้ใน "รายการที่ 59: อย่าเขียนการใช้เนมสเปซในไฟล์ส่วนหัวหรือก่อน # รวม" ของหนังสือมาตรฐานการเข้ารหัส C ++: กฎ 101 ข้อหลักเกณฑ์และแนวทางปฏิบัติที่ดีที่สุด:
กล่าวโดยย่อ: คุณสามารถและควรใช้เนมสเปซโดยใช้การประกาศและคำสั่งอย่างเสรีในไฟล์การนำไปใช้งานของคุณหลังจาก#include
คำสั่งและรู้สึกดีกับมัน แม้จะมีการยืนยันซ้ำ ๆ ในทางตรงกันข้าม แต่เนมสเปซที่ใช้การประกาศและคำสั่งก็ไม่ได้ชั่วร้ายและไม่ได้เอาชนะจุดประสงค์ของเนมสเปซ แต่เป็นสิ่งที่ทำให้เนมสเปซใช้งานได้
Stroupstrup มักจะอ้างว่า "อย่าทำให้เนมสเปซทั่วโลกเป็นมลพิษ" ใน "ภาษาโปรแกรม C ++ รุ่นที่สาม" อันที่จริงเขาพูดแบบนั้น (C.14 [15]) แต่อ้างถึงบทที่ C.10.1 ที่เขาพูดว่า:
การประกาศใช้เพิ่มชื่อให้กับขอบเขตโลคัล ใช้-สั่งไม่ได้; เพียงแค่แสดงชื่อที่สามารถเข้าถึงได้ในขอบเขตที่มีการประกาศ ตัวอย่างเช่น:
namespaceX {
int i , j , k ;
}
int k ;
void f1()
{
int i = 0 ;
using namespaceX ; // make names from X accessible
i++; // local i
j++; // X::j
k++; // error: X::k or global k ?
::k ++; // the global k
X::k ++; // X’s k
}
void f2()
{
int i = 0 ;
using X::i ; // error: i declared twice in f2()
using X::j ;
using X::k ; // hides global k
i++;
j++; // X::j
k++; // X::k
}
ชื่อที่ประกาศในเครื่อง (ประกาศโดยการประกาศธรรมดาหรือโดยการประกาศโดยใช้) จะซ่อนการประกาศที่ไม่ใช่คนในท้องถิ่นที่มีชื่อเดียวกันและตรวจพบการโอเวอร์โหลดของชื่อที่ผิดกฎหมาย ณ จุดประกาศ
หมายเหตุ: ข้อผิดพลาดคลุมเครือสำหรับในk++
f1()
ชื่อส่วนกลางไม่ได้รับการกำหนดค่าตามความชอบเหนือชื่อจากเนมสเปซที่เข้าถึงได้ในขอบเขตส่วนกลาง สิ่งนี้ให้การป้องกันอย่างมีนัยสำคัญจากการปะทะกันของชื่อโดยบังเอิญและที่สำคัญ - ช่วยให้มั่นใจได้ว่าจะไม่มีข้อดีใด ๆ ที่จะได้รับจากการสร้างมลพิษให้กับเนมสเปซทั่วโลก
เมื่อไลบรารีที่ประกาศชื่อจำนวนมากสามารถเข้าถึงได้โดยใช้คำสั่งเป็นข้อได้เปรียบที่สำคัญที่การขัดแย้งกันของชื่อที่ไม่ได้ใช้จะไม่ถือว่าเป็นข้อผิดพลาด
...
ฉันหวังว่าการใช้ชื่อสากลในโปรแกรมใหม่ที่ใช้เนมสเปซลดลงอย่างมากเมื่อเทียบกับโปรแกรม C และ C ++ แบบเดิม กฎสำหรับเนมสเปซถูกสร้างขึ้นโดยเฉพาะเพื่อไม่ให้เกิดประโยชน์กับผู้ใช้ชื่อสากลที่ '' ขี้เกียจ '' เหนือคนที่ดูแลไม่ให้เกิดมลพิษในขอบเขตทั่วโลก
และมีข้อได้เปรียบเช่นเดียวกับ 'ผู้ใช้ชื่อทั่วโลกที่ขี้เกียจ' อย่างไร? โดยการใช้ประโยชน์จากการใช้-สั่งซึ่งได้อย่างปลอดภัยทำให้ชื่อใน namespace สามารถใช้ได้กับขอบเขตปัจจุบัน
โปรดทราบว่ามีความแตกต่าง - ชื่อในstd
เนมสเปซที่พร้อมใช้งานในขอบเขตที่มีการใช้คำสั่งใช้อย่างเหมาะสม (โดยการวางคำสั่งไว้หลัง#includes
) จะไม่ก่อให้เกิดเนมสเปซส่วนกลาง เพียงแค่ทำให้ชื่อเหล่านั้นใช้งานได้ง่ายและมีการป้องกันการปะทะ