Câu trả lời:
Bí danh không gian tên là một cách thuận tiện để tham chiếu đến một tên không gian tên dài bằng một tên khác, ngắn hơn.
Ví dụ: giả sử bạn muốn sử dụng các vectơ số từ uBLAS của Boost mà không cần lệnh using namespace
. Nói rõ không gian tên đầy đủ mỗi lần là cồng kềnh:
boost::numeric::ublas::vector<double> v;
Thay vào đó, bạn có thể định nghĩa một bí danh cho boost::numeric::ublas
- giả sử chúng tôi muốn viết tắt từ này thành ublas
:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Rất đơn giản, #define sẽ không hoạt động.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
Biên dịch tốt. Cho phép bạn làm việc xung quanh không gian tên / xung đột tên lớp.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
Trên dòng cuối cùng, "Hmm: Oops" là một lỗi biên dịch. Bộ xử lý trước thay đổi nó thành Nope :: Oops, nhưng Nope đã là một tên lớp.
Thêm thông tin về chủ đề này http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
Đó là tất cả về việc chọn một bí danh cho một tên không gian tên looong, chẳng hạn như:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Sau đó, bạn có thể typedef
typedef SHORT::mytype
thay vì
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
Cú pháp này chỉ hoạt động cho các không gian tên, không thể bao gồm các lớp, các loại sau namespace NAME =
Cũng lưu ý rằng các bí danh không gian tên và sử dụng các lệnh được giải quyết tại thời gian biên dịch, không phải thời gian chạy. (Cụ thể hơn, cả hai đều là công cụ được sử dụng để báo cho trình biên dịch biết nơi khác cần tìm khi phân giải tên, nếu nó không thể tìm thấy một ký hiệu cụ thể trong phạm vi hiện tại hoặc bất kỳ phạm vi chính nào của nó.) biên dịch:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
Bây giờ, một trí óc tò mò có thể nhận thấy rằng constexpr
các biến cũng được sử dụng tại thời điểm biên dịch và tự hỏi liệu chúng có thể được sử dụng cùng với bí danh hoặc chỉ thị hay không. Theo hiểu biết của tôi, họ không thể, mặc dù tôi có thể sai về điều này. Nếu bạn cần làm việc với các biến có tên giống hệt nhau trong các không gian tên khác nhau và chọn giữa chúng một cách linh hoạt, bạn sẽ phải sử dụng các tham chiếu hoặc con trỏ.
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
Sự hữu ích của những điều trên có thể bị hạn chế, nhưng nó sẽ phục vụ mục đích.
(Lời xin lỗi của tôi cho bất kỳ lỗi đánh máy nào tôi có thể đã bỏ lỡ ở trên.)
Không gian tên được sử dụng để ngăn ngừa xung đột tên.
Ví dụ:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
Bây giờ bạn có hai thanh tên lớp, hoàn toàn khác nhau và tách biệt nhờ vào không gian tên.
"Sử dụng không gian tên" mà bạn hiển thị là để bạn không phải chỉ định không gian tên để sử dụng các lớp trong không gian tên đó. tức là std :: string trở thành chuỗi.
tài nguyên của tôi: https://www.quora.com/What-is-namespace-in-C++-1