Rất nhiều câu trả lời hợp lý rồi. Tôi sẽ đưa ra một sự tương tự có thể giúp một số độc giả. ::
hoạt động rất giống như trình phân tách thư mục hệ thống tập tin ' /
', khi tìm kiếm đường dẫn của bạn cho một chương trình bạn muốn chạy. Xem xét:
/path/to/executable
Điều này rất rõ ràng - chỉ có một tệp thực thi tại vị trí chính xác đó trong cây hệ thống tệp có thể phù hợp với đặc điểm kỹ thuật này, bất kể PATH có hiệu lực. Tương tự ...
::std::cout
... Cũng rõ ràng không kém trong "cây" không gian tên C ++.
Tương phản với các đường dẫn tuyệt đối như vậy, bạn có thể định cấu hình các shell UNIX tốt (ví dụ zsh ) để giải quyết các đường dẫn tương đối trong thư mục hiện tại của bạn hoặc bất kỳ phần tử nào trong PATH
biến môi trường của bạn , vì vậy PATH=/usr/bin:/usr/local/bin
, nếu và bạn đã "vào" /tmp
, thì ...
X11/xterm
... sẽ vui vẻ chạy /tmp/X11/xterm
nếu tìm thấy, khác /usr/bin/X11/xterm
, khác /usr/local/bin/X11/xterm
. Tương tự, giả sử bạn đang ở trong một không gian tên được gọi X
và có using namespace Y
hiệu lực " ", sau đó ...
std::cout
... có thể được tìm thấy trong bất kỳ ::X::std::cout
, ::std::cout
, ::Y::std::cout
, và những nơi có thể khác do tra cứu luận phụ thuộc (ADL, aka Koenig tra cứu). Vì vậy, chỉ ::std::cout
thực sự rõ ràng về chính xác đối tượng của bạn, nhưng may mắn thay, không ai trong tâm trí bên phải của họ sẽ tạo ra lớp / cấu trúc hoặc không gian tên riêng của họ được gọi là " std
", hoặc bất cứ thứ gì gọi là " cout
", vì vậy trong thực tế chỉ sử dụng std::cout
là tốt.
Sự khác biệt đáng chú ý :
1) shell có xu hướng sử dụng trận đấu đầu tiên bằng cách sử dụng thứ tự trong PATH
khi C ++ gây ra lỗi trình biên dịch khi bạn không rõ ràng.
2) Trong C ++, các tên không có bất kỳ phạm vi hàng đầu nào có thể được khớp trong không gian tên hiện tại, trong khi hầu hết các shell UNIX chỉ làm điều đó nếu bạn đặt .
vào PATH
.
3) C ++ luôn tìm kiếm không gian tên toàn cầu (giống như có /
ngầm định của bạn PATH
).
Thảo luận chung về không gian tên và nhân chứng của các biểu tượng
Sử dụng tuyệt đối ::abc::def::...
"đường dẫn" đôi khi có thể hữu ích để cách ly bạn khỏi mọi không gian tên khác mà bạn đang sử dụng, một phần nhưng không thực sự có quyền kiểm soát nội dung hoặc thậm chí các thư viện khác mà mã máy khách của thư viện của bạn cũng sử dụng. Mặt khác, nó cũng kết nối bạn chặt chẽ hơn với vị trí "tuyệt đối" hiện tại của biểu tượng và bạn bỏ lỡ những lợi thế của việc kết hợp ngầm trong không gian tên: ít khớp nối hơn, di chuyển mã dễ dàng hơn giữa các không gian tên và mã nguồn dễ đọc hơn, ngắn gọn hơn .
Như với nhiều thứ, đó là một hành động cân bằng. C ++ chuẩn puts nhiều định danh dưới std::
mà ít "độc đáo" hơn cout
, đó là các lập trình viên có thể sử dụng cho một cái gì đó hoàn toàn khác nhau trong mã của họ (ví dụ như merge
, includes
, fill
, generate
, exchange
, queue
, toupper
, max
). Hai thư viện không liên quan không liên quan có cơ hội sử dụng cùng số định danh cao hơn nhiều vì các tác giả thường không biết hoặc ít biết về nhau. Và các thư viện - bao gồm thư viện C ++ Standard - thay đổi ký hiệu của chúng theo thời gian. Tất cả điều này có khả năng tạo ra sự mơ hồ khi biên dịch lại mã cũ, đặc biệt là khi đã sử dụng nhiều using namespace
s: điều tồi tệ nhất bạn có thể làm trong không gian này là cho phépusing namespace
s trong các tiêu đề để thoát khỏi phạm vi của các tiêu đề, sao cho một lượng lớn mã khách hàng trực tiếp và gián tiếp không thể tự đưa ra quyết định về việc sử dụng không gian tên nào và cách quản lý sự mơ hồ.
Vì vậy, hàng đầu ::
là một công cụ trong hộp công cụ của lập trình viên C ++ để chủ động phân tán một cuộc đụng độ đã biết và / hoặc loại bỏ khả năng mơ hồ trong tương lai ....
::
có nghĩa là tham chiếu biến từ không gian tên toàn cầu / ẩn danh.