名称空间、using声明、using编译指令

C++关于全局变量和局部变量的规则定义了一种名称空间层次,每个声明区域都可以声明名称,这些名称独立于其他声明区域中声明的名称。一个名称空间中的名称不会与另外一个名称空间的相同名称发生冲突,同时允许程序的其他部分使用该名称空间中声明的东西。

名称空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中。因此,在默认情况下,在名称空间中声明的名称的链接性为外部的。

名称空间是开放的,可以把名称加入到已有的名称空间中。如:
namespace Jill{
 char *goose(const char*);
}

可以通过作用域解析操作符::来访问给定名称空间中的名称。
我们不希望每次使用名称时都对它进行限定,因此C++提供了using声明和using编译指令来简化对名称空间中名称的使用。using声明使特定的标识符可用,using编译指令使整个名称空间可用。
using声明被限定的名称和它前面的关键字using组成:
using Jill::fetch;
它将特定的名称添加到它所属的声明区域中。
namespace Jill{
 double fetch;
}
char fetch;
int main()
{
 using Jill::fetch;
 double fetch;//error,already have a local fetch
 cin>>fetch;//读入一个数据到Jill::fetch,覆盖了全局fetch
 cin>>::fetch;//读入一个数据到全局fetch中
}
在函数的外面使用using声明,则把名称添加到全局名称空间中。

using编译指令由名称空间名和它前面的using namespace组成。在全局声明区域中使用using编译指令,将使该名称空间的名称全局可用;在函数中使用using编译指令,将使其中的名称在该函数中可用。

using声明和using编译指令增加了名称冲突的可能性,也就是说,如果有名称空间jack和jill,并在代码中使用作用域解析操作符,则不会存在二义性:
jack::pal=3;
jill::pal=10;
上述两个变量是不同的标识符,表示不同的内存单元,然而,使用using声明:
using jack::pal;
using jill::pal;
pal=4;
编译器将不允许您同时使用上述两个using声明,因为这会导致二义性。

using编译指令和using声明的比较:
使用using编译指令导入一个名称空间的所有名称和使用多个using声明是不一样的,using编译指令更像是大量使用作用域解析操作符。
使用using声明时,就像声明了相应的名称一样,如果某个名称已经在函数中声明了,则不能用using声明导入相同的名称。
然而,使用using编译指令时,将进行名称解析,就像在包含using声明和名称空间本身的最小声明区域中声明了名称一样。
在下面的范例中,名称空间是全局的,如果使用using编译指令导入一个已经在函数中声明的名称,则局部名称将隐藏名称空间名,就像隐藏同名的全局变量一样:
namespace jill{
 double fetch;
 double bucket(double n){};
 struct hill{};
}
char fetch;
int main(){
 using namespace jill;//导入名称空间里的所有名称
 hill thrill;//创建一个jill::hill的结构
 double water=bucket(2);//使用jill::bucket
 double fetch;//不报错,它隐藏了jill::fetch
 cin>>fetch;//读入到局部fetch
 cin>>::fetch;//读入到全局fetch
 cin>>jill::fetch;//读入到jill::fetch
}
int foom{
 hill top;//错误、
 jill::hill crest;//正确
}
虽然函数中的using编译指令将名称空间的名称视为在函数之外声明的,但它不会使得该文件中的其他函数能够使用这些名称。

记住:假设名称空间和声明区域定义了相同的名称,如果使用using声明将名称空间的名称导入该声明区域,则两个名称会发生冲突而出错;如果使用using编译指令,则局部版本将会隐藏名称空间版本。因此一般来说,using声明比using编译指令要安全,这是因为它只导入指定的名称。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值