命名空间:
(1)由于现在软件规模越来越大,不可避免由很多人合作开发,这样就必然会产生全局变量(函数,类等)命名冲突的问题。所以在C++等语言中引入了namespace解决这个问题。namespace允许像类,对象,函数聚集在一个名字下,从本质上来讲namespace是对全局作用域的细分,允许同名全局变量(函数,类等)的定义。
例如:
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,但是他们不在同一个namespace中所以没有冲突。
(2)为了在namespace外使用namespace内的变量我们使用::操作符,显然是比较麻烦的。我们可以使用命令空间中的关键字using从namespace中引入名字到当前作用域。Using可以导入整个命名空间,如using namespace std,也可以只导入命名空间某个变量(函数,类等),如using namespace std::cout。
但是如果同时用using namespace声明多个命名空间时,可能会出错。如上面程序中的main函数如果用下面程序段代替,就会出错。
int main()
{
using namespace first;
using namespace second;
cout << var << endl;
cout << var << endl;
return 0;
}
因为在同一作用域中同时引入了两个命名空间first和second,在出现var时,无法判定是哪个命名空间中的,出现二义性,编译出错。如果using指令局限在很小的作用域中,这样他们的效用就会受到限制并且易于使用。如:
int main()
{
{
using namespace first;
cout << var << endl;
}
{
using namespace second;
cout << var << endl;
}
return 0;
}
这样就不会有重复定义的问题了。
(3)命名空间也可以嵌套定义
namespace first
{
int a=10;
int b=20;
namespace second
{
double a=1.02;
double b=5.002;
void hello();
}
void second::hello()
{
std::cout <<"hello world"<<std::endl;
}
}
int main()
{
using namespace first;
std::cout<<second::a<<std::endl;
second::hello();
}
输出是1.02 hello world,在namespace first中嵌套了namespace second,seond并不能直接使用,需要first来间接的使用。
(4)可以为命名空间起一个别名(namespace alias),用来代替较长的命名空间名。如
namespace Television //声明命名空间,名为Television
{ ... }
可以用一个较短而易记的别名代替它。如:
namespace TV=Television; //别名TV与原名Television等价
也可以说,别名TV指向原名Television,在原来出现Television的位置都可以无条件地用TV来代替。
(5)无名的命名空间,C++还允许使用没有名字的命名空间,如在文件A中声明了以下的无名命名空间:
namespace //命名空间没有名字
{ void fun( ) //定义命名空间成员
{ cout<<"OK."<<endl;}
}
由于命名空间没有名字,在其他文件中显然无法引用,它只在本文件的作用域内有效。无名命名空间的成员fun函数的作用域为文件A(确切地说,是从声明无名命名空间的位置开始到文件A结束)。在文件A中使用无名命名空间的成员,不必(也无法)用命名空间名限定。
如果在文件A中有以下语句:
fun();
则执行无名命名空间中的成员fun函数,输出”OK.”。
在本程序中的其他文件中也无法使用该fun函数,也就是把fun函数的作用域限制在本文件范围中。可以联想到:在C浯言中可以用static声明一个函数,其作用也是使该函数的作用域限于本文件。C++保留了用static声明函数的用法,同时提供了用无名命名空间来实现这一功能。随着越来越多的C++编译系统实现了ANSI C++建议的命名空间的机制,相信使用无名命名空间成员的方法将会取代以前习惯用的对全局变量的静态声明。