## 5.2 名空间 (Namespaces)
通过使用名空间(Namespaces)我们可以将一组全局范围有效的类、对象或函数组织到一个名字下面。换种说法,就是它将全局范围分割成许多子域范围,每个子域范围叫做一个名空间(namespaces).
使用名空间的格式是:
~~~
namespace identifier { namespace-body }
~~~
这里identifier 是一个有效的标示符,namespace-body 是该名空间包含的一组类、对象和函数。例如:
~~~
namespace general { int a, b; }
~~~
在这个例子中,a 和 b 是名空间general中的整型变量。要想在这个名空间外面访问这两个变量,我们必须使用范围操作符::。例如,要想访问前面的两个变量,我们需要这样写:
`general::a
general::b`
名空间(namespaces)的作用在于全局对象或函数很有可能重名而造成重复定义的错误,名空间的使用可以避免这些错误的发生。例如:
~~~
// namespaces
#include <iostream.h>
namespace first {
int var = 5;
}
namespace second {
double var = 3.1416;
}
int main () {
cout << first::var << endl;
cout << second::var << endl;
return 0;
}
~~~
| 5
3.1416 |
在这个例子中,两个都叫做var全局变量同时存在,一个在名空间first 下面定义,另一个在 second下面定义,由于我们使用了名空间,这里不会产生重复定义的错误。
### 名空间的使用 (using namespace)
使用 using 指令后面跟namespace可以将当前的嵌套层与一个指定的名空间连在一起,以便使该名空间下定义的对象和函数可以被访问,就好像它们是在全局范围内被定义的一样。它的使用遵循以下原型定义:
`using namespace identifier;`
例如:
~~~
// using namespace example
#include <iostream.h>
namespace first {
int var = 5;
}
namespace second {
double var = 3.1416;
}
int main () {
using namespace second;
cout << var << endl;
cout << (var*2) << endl;
return 0;
}
~~~
| 3.1416
6.2832 |
在这个例子中的main函数中可以看到,我们能够直接使用变量var 而不用在前面加任何范围操作符。
这里要注意,语句using namespace 只在其被声明的语句块内有效(一个语句块指在一对花括号{}内的一组指令),如果using namespace是在全局范围内被声明的,则在所有代码中都有效。例如,如果我们想在一段程序中使用一个名空间,而在另一段程序中使用另一个名空间,则可以像以下代码中那样做:
~~~
// using namespace example
#include <iostream.h>
namespace first {
int var = 5;
}
namespace second {
double var = 3.1416;
}
int main () {
{ using namespace first;
cout << var << endl;
} { using namespace second;
cout << var << endl;
}
return 0;
}
~~~
| 5
3.1416 |
### 别名定义(alias definition)
我们以可以为已经存在的名空间定义别名,格式为:
`namespace new_name = current_name ;`
### 标准名空间(Namespace std)
我们能够找到的关于名空间的最好的例子就是标准C++ 函数库本身。如ANSI C++ 标准定义,标准C++库中的所有类、对象和函数都是定义在名空间std下面的。
你可能已经注意到,我们在这个教程中全部忽略了这一点。作者决定这么做是因为这条规则几乎和ANSI 标准本身一样年轻 (1997) ,许多老一点的编译器并不兼容这条规则。
几乎所有的编译器,即使是那些与ANSI 标准兼容的编译器,都允许使用传统的头文件 (如iostream.h, stdlib.h, 等等),就像我们在这个教程中所使用的一样。然而,ANSI标准完全重新设计了这些函数库,利用了模板功能,而且遵循了这条规则将所有的函数和变量定义在了名空间std下。
该标准为这些头文件定义了新的名字,对针对C++的文件基本上是使用同样的名字,但没有.h的扩展名,例如, iostream.h 变成了iostream。
如果我们使用ANSI-C++ 兼容的包含文件,我们必须记住所有的函数、类和对象是定义在名空间 std 下面的,例如:
~~~
// ANSI-C++ compliant hello world
#include <iostream>
int main () {
std::cout << "Hello world in ANSI-C++\n"; return 0; }
~~~
| Hello world in ANSI-C++ |
更常用的方法是使用using namespace ,这样我们就不必在所有标准空间中定义的函数或对象前面总是使用范围操作符::了 :
|
~~~
// ANSI-C++ compliant hello world (II)
#include <iostream>
using namespace std;
int main () {
cout << "Hello world in ANSI-C++\n";
return 0;
}
~~~
| Hello world in ANSI-C++ |
对于STL 用户,强烈建议使用ANSI-compliant 方式来包含标准函数库。