这篇博文主要讲了名称空间,说实话在接触之前一直对这方面很感兴趣,现在来好好的学习一番。
7.1 新的名称空间特性
C++新增了这样一种功能,即通过定义一种新的声明区域来创建命名的名称空间,这样做的目的之一是提供一个声明名称的区域。一个名称空间的名称不会与另外一个空间的名称发生冲突,同时允许程序的其他部分使用该名称中声明的东西。比如,下面的代码使用关键字namespace创建了名称空间:
namespace Jack { double pail; void fetch(); int pal; struct Well{... }; } namespace Jill { double bucket(double n){... } double fetch; int pal; struct Hill{... }; }
可以通过作用域解析符来::来访问名称空间的名称
Jack::pail=12.34; JIll::Hill mole;
7.2 using声明和using编译指令
我们不希望每次使用名称空间的时候都对其进行限定,因此C++提供了两种机制(using声明和using编译指令)来简化对名称空间的使用。using声明有被限定的名称和它前面的关键字using组成;它将特定的名称加在它所属的声明区域中,比如
int main() { using Jill::fetch; double fetch;//error!already have alocal namespace cin>>fetch;//into Jill::fetch cin>>::fetch;//into global fetch ... }
另外,在函数外面使用using时会把名称添加到全局的名称空间中。using声明使一个名称可用,而using编译指令是所有的名称都可用。using编译指令有名称空间名和它前面的关键字using namespace组成,它是名称空间的所有名称都可用,而不需要使用作用域解析符,如下面的代码
using namespace Jack; #include<iostream> using namespace std;
7.3 using声明与using编译指令之间的比较
使用using编译指令导入一个名称空间的所有名称与使用多个using声明是不一样的,而更像是大量使用作用域解析运算符。使用using声明,就好像声明了相应的名称一样。比如某个名称已经出现在函数中声明了,则不能使用using声明导入相同的名称。然而,使用using编译指令时,将进行名称解析。如果使用using编译指令导入一个已经存在函数中声明的名称,则局部名称将隐藏名称空间名,就像隐藏同名的变量一样。
namespace Jill{... }; char fetch; int main() { using namespace Jill; Hill Thriller; double fetch;//not an error;hide Jill fetch cin>>fetch;//into local fecth cin>>::fetch;//into global fetch cin>>Jill::fetch;//into Jill::fetch ... }
同7.2我们可以简单的发现如果试图使用using声明将名称空间导入该声明区域,则这两个名称会发生冲突,从而出错。如果使用using编译指令将该名称空间的名称导入该声明区域,则局部版本将隐藏名字空间版本
7.4 名称空间的其他特性
可以讲名称空间进行嵌套
namespace elsements { namespace fire { int flame; ... } float water; }
这里flame指得是element::fire::flame.同样也可以使用编译指令using namespace elsements::fire;
另外我们还可以这样命名名字空间
namespace myth { using Jill::fetch; using namespace elsements; using std::cout; using std::cin; }
7.5 名字空间及其前途
下面是当前的一些指导原则
- 使用在已命名的名称空间中的变量,而不是使用外部全局变量。
- 使用在已命名的名字空间中声明的变量,而不是使用静态全局变量。
- 如果开发了一个函数库或者是类库,将其放在一个名字空间中。事实上,C++当前提倡将标准的函数库放在名称空间std中,这种做法扩展到了C语言中的函数。
- 仅将编译指令using作为紫红旧代码转换为使用工程空间的权宜之计。
- 不要在头文件中使用using编译指令。首先这样做掩盖了要让哪些名称可用;另外,包含头文件的顺序可能影响程序的行为。如果非要使用,最好用在#include之后。
- 导入名称时,首先选用作用域解析运算符或using声明的方法。
- 对于using声明,首选将其作用域设置为局部而不是全局。
好了,名称空间大概就讲这么多了。之后就要进入类这个概念了,这一部分很重要,要好好写啊。