为什么要用名称空间
我们首先想知道我们为什么需要一个名称空间呢?它有什么用呢?我们先看下面这个例子
比如有
- A厂写的代码里面包含了一个函数wanda()
- B厂写的代码里面也包含了一个函数wanda()
此时如果你想把A B两个厂商的代码组合起来,就有可能会发生函数名字冲突这样的事情。
而名称空间能让厂商把其产品封装在一个叫做名称空间的单元中,这样就可以使用名称空间来指出想用哪个厂商的产品。
比如使用A公司的wanda()函数可以这样写
A:wanda();
使用B公司的wanda()函数可以这样写
B::wanda();
传统的C++名称空间
声明区域(declaration region)
声明区域顾名思义就是可以在其中进行声明的区域。例如,可以在函数外面声明全局变量,对于这种变量,其声明区域为其所在的文件。对于在函数中声明的变量,其声明区域为其声明所在的代码块。
潜在作用域(potential scope)
第二个需要知道的术语是潜在作用域( potential scope)。变量的潜在作用域从声明点开始,到其声明区域的结尾。因此潜在作用域比声明区域小,这是由于变量必须定义后才能使用。
上面给大家讲述了两个术语,在这里问大家一个问题,是否变量在其潜在作用域都是可见的呢?
比如如下代码所示,我们这里定义了两个i
一个是在外面,已在是在for(int i=0;i<9;i++)
里面,这段代码的输出如图1所示
#include <iostream>
int main()
{
using namespace std;
int i = 100;
for (int i = 0;i < 9;i++) {
cout << i << endl;
}
}
图1
可以看到第一个定义的i
被掩盖了;故我们得出如下结论,变量并非在其潜在作用域都是可见的,它可能被另一个在嵌套声明区域中声明的同名变量隐藏
故我们知道为什么叫做潜在作用域,因为它可能不是真正的作用域,变量对于程序而言可见的范围被称作作用域(scope),这是第三个术语。
作用域(scope)
变量对于程序而言可见的范围,是潜在作用域的子集 下图2 充分的展示了两者的关系
图2
C++ 新的名称空间特性
上面展示的是旧的C++的名称空间的特性,接下来我们详细展示一下C++新的名称空间的特性,新的C++特性在原有的命名空间的基础上定义了一种新的声明区域来创建命名的名称空间,这样做的目的之一如开头所言,为了写大型代码和协作的时候没那么容易发生冲突。关于新的名称空间有以下几点特性。
- 名称空间可以是全局的,也可以嵌套即位于另外一个名称空间中
- 除了用户定义的名称空间外,还存在另一个名称空间全局名称空间(global namespace),它对应于文件级声明区域,具体来说,你定义的全局变量都位于这个空间之中。
- 名称空间是开放的,你可以把新的名称加入到已有的名称空间中去。如下代码表示将名称
goose
加入到Jill中的名称列表中。namespace Jill{ char *goose(const char*); }
- 名称空间亦可以修改已有名称空间中的函数的代码。
namespace Jack{ void fetch(){ …… } }
名称空间的使用
using声明和using编译指令
我们在C++中经常使用using
这一关键字,但是其实它有两种用法,一种是作声明 一种是做编译指令
using做声明
using Jill::fetch;//使用using 作声明
using做编译指令
using namespace std;