1. 嵌套的命名空间
命名空间可以嵌套,嵌套的命名空间可以进一步改进库中代码的组织。
namespace cplusplus_primer { namespace QueryLib { class Query { /* … */ }; // … } namespace Bookstore { class Item_base { /* … */ }; // … } }
当需要防止库中每个部分的名字与库中其他部分的名字冲突的时候,嵌套命名空间是很有用的。使用时,类Query的完全限定名如下:cplusplus_primer::QueryLib::Query。
2. 匿名的命名空间
匿名的命名空间可以在给定文件中不连续,但不能跨越多个文件。
匿名的命名空间用于声明局部于文件的实体,在匿名的命名空间中定义的变量在程序开始时创建,在程序结束时一直存在。
匿名的命名空间中定义的名字可直接使用,没有完全限定名。
匿名的命名空间中定义的名字只在本文件中可见。
匿名的命名空间中定义的名字可以在定义该命名空间所在的作用域中可见,如果在文件的最外层作用域中定义匿名的命名空间,那么该匿名的命名空间中的名字必须与全局作用域中的名字不同。
int i; namespace { int i; } i = 10; // error: ambiguous defined globally and in an unnested, unnamed namespace
匿名的命名空间可以嵌套在另一个命名空间内部。
namespace local { namespace { int i; } } // ok: i defined in a nested unnamed namespace is distinct from global i local::i = 42;
注意:如果头文件定义了匿名的命名空间,那么在每个包含该头文件的文件中,都将定义该名字的不同的局部实体。
匿名的命名空间有一个重要的用处,就是取代文件中的静态声明。在c语言中,程序必须将名字声明为static,才可以使其局部于一个文件,而对其它的文件不可见。c++继承了这个特性,但c++不赞成这种文件静态声明。不赞成的特性就可能会在未来的版本中不支持,所以应该使用匿名的命名空间来代替static静态声明。