有这样一种情况,当一所学校同一班级有两个姓名相同的学生时,假设他们都叫张三,我们要分辨出这两个学生就需要添加额外的信息,比如来自河南的张三,来自河北的张三。这样就能够分别出这两个人了。
c++应用程序中也可能出现同样的情况。例如,你可能正在编写一些代码,其中包含一个名为hello()的函数,而另一个可用的库也具有相同的hello()函数。现在,编译器无法知道你在代码中引用的hello()函数的哪个版本。
命名空间(namespace)就是为了克服这一困难而设计的,它被用作附加信息来区分不同库中具有相同名称的类似函数、类、变量等。本质上,名称空间定义了一个范围,有着封装和解决命名冲突这两个好处。
名称空间定义以关键字namespace
开头,后跟名称空间名称,如下所示
namespace TestNamespace
{
int x;
void f() {};
}
// 为了调用包含在`namespace`的函数或变量,需要做以下示例操作
int main()
{
TestNamespace::x;
TestNamespace::f();
}
接下来看看怎么使用命名空间范围内的函数,变量等实体的,如下所示:
#include <iostream>
namespace FirstTest
{
int x;
void func()
{
std::cout << "In First Test!" << std::endl;
}
}
namespace SecondTest
{
int x;
void func()
{
std::cout << "In Second Test!" << std::endl;
}
}
int main()
{
// 调用FirstTest里的func函数
FirstTest::func();
FirstTest::x = 3;
// 调用SecondTest里的func函数
SecondTest::func();
SecondTest::x = 5;
std::cout << FirstTest::x << " " << SecondTest::x;
return 0;
}
//OUTPUT
/*
In First Test!
In Second Test!
3 5
*/
使用using namespace
可避免使用namespace指令将名称空间作为前缀。此指令告诉编译器后续代码使用指定名称空间中的名称。命名空间因此被隐含在下面的代码中
#include <iostream>
namespace FirstTest
{
int x;
void func()
{
std::cout << "In First Test!" << std::endl;
}
}
namespace SecondTest
{
int x;
void func()
{
std::cout << "In Second Test!" << std::endl;
}
}
using namespace FirstTest;
int main () {
// 调用FirstTest里的func函数
func();
return 0;
}
// 编译并运行上述代码,这将产生以下结果
/*
In First Test!
*/
using
指令也可以用来引用命名空间中的特定项。例如,如果你打算使用的标准库(标准库的命名空间为std)std中的cout一个函数,那么可以如下所示引用它
#include <iostream>
using std::cout;
int main()
{
cout << "std::endl is used with std! but cout not!" << std::endl;
return 0;
}
// OUTPUT
/*
std::endl is used with std! but cout not!
*/
这里做一点补充,using在c++中还可以当做C语言typedef的作用定义一个新的类型。
注: 通过using指令中引入的名称符合正常的范围规则。从using指令的角度来说名称在指令的整个作用域(生命周期内)(开始和末尾)都可见。但是外部范围中定义的同名实体其实应该是隐藏的。
命名空间可以定义为几个部分,因此命名空间是由其各自定义的部分的总和组成的。命名空间的不同部分可以分布在多个文件中。
因此,如果命名空间的一部分需要在另一个文件中定义的名称,则仍然必须声明该名称。编写下面的命名空间定义,要么定义一个新的名称空间,要么在现有的命名空间中添加新的元素。
命名空间可以嵌套,您可以在另一个命名空间中定义一个命名空间,如下所示
namespace Name1
{
namespace Name2
{
}
}
// 可以使用如下操作符访问嵌套名称空间的成员
// 访问Name2的成员
using namespace Name1::Name2;
// 访问Name1的成员
using namespace Name1;
在上面的语句中,如果使用using Name1
,那么它将使Name2
的元素在作用域中可用,如下所示
#include <iostream>
using namespace std;
namespace Name1
{
void func()
{
cout << "Inside Name1's space" << endl;
}
namespace Name2
{
void func()
{
cout << "Inside Name2's space" << endl;
}
}
}
using namespace Name1;
int main () {
func();
// 这将从第二个名称空间调用函数。
Name2::func();
return 0;
}
// OUTPUT
/*
Inside Name1's space
Inside Name2's space
*/