分类: WINDOWS
2012-02-28 16:49:44
[1] 带限定词的名字
因为名字空间就是作用域,所以普通的作用域规则也对名字空间成立。因此,如果一个名字先前已在空间或者外围作用域里声明过,就可以直接使用,不必再进一步为它操心了。也可以使用来自另一个名字空间的名字,但需要在名字空间作为限定词。
典型用法如 std::cout<<..... ; 的使用,名字cout即是定义在标准名字空间std当中。
[2] 使用声明
显然,当某个名字在它自己的名字空间之外频繁使用时,在反复写它时都要加上名字空间来作限定词,是一件令人厌烦的事情。这时,可以通过一个使用声明而清楚掉,只需要在某个地方说明,在这个作用域其后的代码中,使用此名字时可以自动解析出此名字所在的空间。
典型用法如 using std::cout; 此后在使用 cout 时,都无需再加上名字空间前缘了。
[3] 使用指令
一个使用指令能把来自另一个名字空间的所有名字都变成在当前名字空间内可用,就像这些名字就在当前名字空间中一样。
例如,在一个名字空间内有命令 using namespace std; 则在此后的代码中(当前空间最小局部内),对于所有名字都无需有名字空间前缀即可使用。
应当理解,全局性的使用指令是一种完成转变的工具,而并不只是为了少拼写几个名字空间,在其它方面最好避免使用它,因为他因引入同义词而导致混乱。
在一个名字空间里的使用指令是一种名字空间的组合工具。
在一个函数里(也仅限于这种地方),可以安全的将使用指令作为一个方便的记法方式。
[4] 避免名字冲突
名字空间是为了表示逻辑结构。最简单的这类结构就是分清楚由一个人写的代码与另一个人写的代码。这种简单的划分也可能具有极大的实际重要性。通过上面介绍的三种技术,通过显示的限定,使用声明或者使用指令去使用不同名字空间中可能重复的名字。
[5] 无名的名字空间
在一些情况下,名字空间的作用仅仅是为了保持代码的局部性,这时去发明一个多余的名字就成了人烦恼,还可能偶然地与其它名字相冲突。此时,可以简单的让这个名字空间没有名字。
如:
namespace {
int a; void f(){ /* ... */}
}
显然,必须存在某种方式,使我们可以从一个无名的名字空间之外访问其中的成员。因此,无名空间有一个隐含的使用指令。上面的声明等价于
namesapce $$${
int a; void f(){/* ... */}
}
using namespace $$$
[6]名字空间的别名
如果用户给他们的名字空间名字起得太短,不同名字空间也可能引起冲突;而名字空间太长可能又变得不很实用。这时,可以通过在使用指令中给名字空间提供一个别名来改善情况。
如:namespace s = std; 之后,可以用s来代表名字空间std,s::cout <<... ;
[7] 组合和选择
我们常常需要从现存的界面出发组合出新的界面.方法是在新界面中用使用指令引入已有的界面。在使用新界面的名字时,如果显式限定的名字在所说的名字空间里没有声明,编译器就会查看使用指令说到的名字空间。
只有在我们需要定义什么东西时,才需要知道一个实体真正所在的名字空间。
有时我们只是想从一个名字空间里选用几个名字,通过使用声明来做,可以使从名字空间里选择一些特征的变得更加明确。使用声明将具有指定的名字的每个声明都带入作用域。特别的,通过一个使用声明,将一个重载函数的所有变形都带进来。
将组合(通过使用指令)和选择(通过使用声明)结合起来能产生更多的灵活性,这些也都是真实世界的例子所需要的。依靠这种机制,我们能有这样的方式,它们既能提供许多机制的访问,又能消解由于组合而产生的名字冲突或者歧义性。(在查看一个名字空间时,通过显示声明的方式(包括通过使用声明声明的名字)优先于在其它作用域的那些通过使用指令才能访问的名字。
[8] 名字空间和重载
重载可以跨名字空间工作。对于我们能以最小代价将现存的库修改为使用名字空间的东西而言,这特征是必不可少的。