9.3.2 新的名称空间特性(3)
在main( )中,名称Jill::fetch被放在局部名称空间中,但其作用域不是局部的,因此不会覆盖全局的fetch。然而,局部声明的fetch将隐藏Jill::fetch和全局fetch。然而,如果使用作用域解析运算符,则后两个fetch变量都是可用的。读者应将这个示例与前面使用using声明的示例进行比较。
需要指出的另一点是,虽然函数中的using编译指令将名称空间的名称视为在函数之外声明的,但它不会使得该文件中的其他函数能够使用这些名称。因此,在前一个例子中,foom( )函数不能使用未限定的标识符Hill。
注意:假设名称空间和声明区域定义了相同的名称。如果试图使用using声明将名称空间的名称导入该声明区域,则这两个名称会发生冲突,从而出错。如果使用using编译指令将该名称空间的名称导入该声明区域,则局部版本将隐藏名称空间版本。
一般说来,使用using声明比使用using编译指令更安全,这是由于它只导入指定的名称。如果该名称与局部名称发生冲突,编译器将发出指示。using编译指令导入所有名称,包括可能并不需要的名称。如果与局部名称发生冲突,则局部名称将覆盖名称空间版本,而编译器并不会发出警告。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。
下面是本书的大部分示例采用的方法:
首先,#include语句将头文件iostream放到名称空间std中。然后,using编译指令是该名称空间在main( )函数中可用。有些示例采取下述方式:
这将名称空间std中的所有内容导出到全局名称空间中。使用这种方法的主要原因是方便。它易于完成,同时如果系统不支持名称空间,可以将前两行替换为:
然而,名称空间的支持者希望有更多的选择,既可以使用解析运算符,也可以使用using声明。也就是说,不要这样做:
而应这样做:
或者这样做:
可以用嵌套式名称空间(将在下一节介绍)来创建一个包含常用using声明的名称空间。
3.名称空间的其他特性
可以将名称空间声明进行嵌套:
这里,flame指的是element::fire::flame。同样,可以使用下面的using编译指令使内部的名称可用:
另外,也可以在名称空间中使用using编译指令和using声明,如下所示: