来源:维基百科
在C++语言中,命名空间是一种实体,使用namespace来声明,并使用{ }来界定命名空间的作用域。
例:
namespace foo { int bar; }
命名空间对应于命名空间作用域。和C语言的文件作用域兼容,C++具有全局命名空间作用域,对应的命名空间是全局命名空间,不需要声明。用前缀为::
的qualified-id显式引用全局命名空间作用域中的名称,此外也有特别的用法。例如,::operator new
指称全局new运算符;而::new
指称new表达式使用全局::operator new为创建的对象分配存储。
命名空间可以在另一命名空间之中嵌套声明;但不能声明在类和代码块之中。在命名空间中声明的名称,默认具有外部链接(除非声明的是const对象,它默认是具有内部链接)。
按照是否有名字,可分为有名字的命名空间与无名命名空间。后者的声明为:
namespace { namespace-body(即声明序列(可选)) }
实现会选取一个和其它命名空间名称都不一样的唯一隐含名称为其命名。无名命名空间的成员在本翻译单元中可以不加显式引用(实际上也没法显式引用无名命名空间)而直接使用;但在其他翻译单元中不可见。尽管无名命名空间中的名称仍然具有默认的外部链接,但因为无法和其它命名空间中的名称一样被跨翻译单元引用,可以和静态链接的名称类似被优化。
命名空间的成员,是在命名空间体的花括号内声明了的名称。可以在命名空间体之外,给出命名空间成员的定义。即命名空间的成员声明与定义可以分开。
子命名空间必须定义在上层命名空间体之内。禁止把子命名空间的声明与定义分开。
不能以“命名空间名::成员名;”方式,在命名空间体之外为命名空间添加新成员。必须在命名空间体之中添加新成员的声明。
可以多次声明和定义同一命名空间,每次给这一命名空间添加新成员。同名的命名空间即便在声明位置不同,仍然是同一个实体。
可以在一个命名空间中引入其他命名空间的成员。例如:
namespace myNameSpace{ using namespace His_NameSpace; using OLib::List; void my_func(String &, List &); }
引用命名空间的成员,有下述办法:
- 使用命名空间的作用域解析运算符
::
,如:std::cout
using namespace 命名空间名[::命名空间名…];
该语句使指定的命名空间中的所有成员都可直接使用。如果引入的名称与局部名称发生冲突,则编译器并不会发出任何警告信息,而只是用局部名称自动覆盖命名空间中的同名成员。using 命名空间名::[命名空间名::……]成员名;
引入命名空间中的一个成员。如果引入的名称与局部名称发生同名冲突,编译器会报错。
命名空间可以有别名:namespace 别名 = 命名空间名;
这使得名字较长的命名空间可以方便地用较短的别名来引用。
C++11起支持内联命名空间。使用inline namespace
作为声明的起始。内联命名空间的名称在名称查找时被特别对待,使用qualified-id引用其中的名称时,被内联的命名空间名称可以省略。实用上,内联命名空间可以在修改命名空间名称的同时避免在二进制文件中生成的符号改变,因此不同内联命名空间的名称可以用于标识接口兼容的不同版本,有助于保持二进制兼容性。这也在标准库的实现中被使用,如libstdc++和libc++。