2.6 命名空间
在书写程序的时候,很多时候都要用到namespace,那么这个namespace是什么呢?
2.6.1 命名空间的定义
命名空间(namespace)是一种描述逻辑分组的机制,可以将按某些标准在逻辑上属于同一个集团的声明放在同一个命名空间中。
在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等。在大规模程序的设计中,以及在程序员使用各种各样的C++库时,为了避免这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域。
原来C++标识符的作用域分成三级:如复合语句和函数体、类和全局。现在,在其中的类和全局之间,标准C++又添加了命名空间这个作用域级别。
命名空间可以是全局的,也可以位于另一个命名空间中,但是不能位于类和代码块中。所以,在命名空间中声明的标识符默认具有外部链接特性(除非它引用了常量)。
在所有命名空间之外,还存在一个全局命名空间,它对应文件级的声明域。因此,在命名空间机制中,原来的全局变量,现在被认为位于全局命名空间中。
有两种形式的命名空间——有名的和无名的。
下面通过一个例子来说明如何定义命名空间。
【实例2-7】定义命名空间(代码2-7.txt)
新建名为“mmkjtest”的【C++Source File】源程序,源代码如下所示:
【代码详解】
在本例中,定义了两个命名空间,分别是myown1和myown2,每个命名空间都定义了一个变量。
在主程序中,将各个命名空间的内容输出。
运行结果如图2-8所示。
图2-8 代码运行结果
【实例分析】
从运行结果可以看出,每个命名空间的内容都被很好地调用了。
2.6.2 using关键字
在C++的命名空间中,为了方便使用,又引入了关键字using。利用using声明可以在引用命名空间成员时不必使用命名空间限定符“::”。
使用方法如下:
下面通过一个例子来说明如何使用using关键字。
【实例2-8】using关键字(代码2-8.txt)
新建名为“usingtest”的【C++ Source File】源程序,源代码如下所示:
【代码详解】
在本例中,定义了两个命名空间,分别是myown1和myown2,每个命名空间都定义了一个变量。
在主程序中,使用using关键字调用了myown1的命名空间,在调用第二个命名空间时,没有使用using调用。
运行结果如图2-9所示。
图2-9 代码运行结果
【实例分析】
从运行结果可以看出,每个命名空间的内容都被很好地调用了。
2.6.3 命名空间std
C++标准中引入命名空间的概念是为了解决不同模块或者函数库中相同标识符冲突的问题。有了命名空间的概念,标识符就被限制在特定的范围内,不会引起命名冲突。典型的例子是std命名空间,C++标准库中所有标识符都包含在该命名空间中。
如果确信在程序中引用某个或者某些程序库不会引起命名冲突,那么可以通过using操作符来简化对程序库中标识符(通常是函数)的使用,例如:
那么就可以不用在标识符加前缀std::来使用C++标准库中的函数了。
C++标准引入的std命名空间并不向后兼容目的C++标准库。旧的C++标准库的头文件中声明的标识符是全局范围的,不需要使用std命名空间限定就可以使用。为了区分在标准化进程中的这种变化,C++新的标准库启用了新的头文件命名格式。这样就允许程序员通过包含不同格式的头文件来使用不同的C++标准库。
新的C++标准库的头文件不再包含扩展名(.h、hpp、hxx等),形式如下:
这种新标准同样涵盖C标准库,C标准库的头文件现在可以这样引用:
而这种新格式的头文件中定义的标识符全部涵盖在std命名空间下。
这种新的命名方式的便利之处就在于可以方便地区分旧的C标准库中的头文件和新的C++标准库中的头文件。比如C标准库和C++标准库中原先都有一个<string.h>的头文件,如果同时使用,就会很不方便。现在不存在这样的问题了,形式如下: