今天研究的问题是命名空间和匿名命名空间。
p.s.借这个机会也过了把在Stack Overflow上提问的瘾,想来我是第一次和外国人交流问题^_^
以下代码几乎包括了今天研究的所有内容:
1.匿名命名空间
2.命名空间嵌套
3.命名空间中可以有函数定义
4.命名空间作用域的研究
5.命名空间的访问方式
6.全局命名空间和匿名命名空间
#include
namespace
{
int a=6; //A
int f(void) //B
{
return 0;
}
namespace k //C
{
int a;
}
}
int a=2; //D
int main(void)
{
using std::cout;
using std::endl;
int a=1; //E1
{//block
int a=3; //F
k::a=4; //G
cout<<"namespace k::a="<<::k::a<
cout<<"a in block="<<
cout<<"global a="<<::a<
}
cout<<"a in main="<<
return 0;
}
the new C++ Standard reads in section 7.3.1.1 Unnamed Spaces, paragraph 2:
“The use of the static keyword is deprecated when declaring objects in a
namespace scope, the unnamed namespace provides a superior alternative.”
在没弄明白全局命名空间和匿名命名空间前,我对以下代码挺疑惑:
#include
namespace
{
int a=1;
}
int a=2,b=3;
int main(void)
{
std::cout<<::a<<::b;
return 0;
}
当我尝试使用a时,编译失败,给出了两个候选变量:匿名空间中的a和全局的a
当我使用::a时,我一直期待结果会是13,但是以上程序的输出是23.
然后去Stack Overflow上问了这个问题,终于搞明白点了。
::a是访问全局命名空间的方式,而访问匿名命名空间的方式是使用a,
如果说全局变量中没有叫a的变量存在,才会去找匿名空间中的a,也就解释了为什么当没有全局a的时候,::a和a都表示匿名空间中的a
也就是说,当匿名空间和全局空间都存在时,对于::访问而言,全局空间优先,
不过不建议大家做这种鸟实验,毕竟没有人会故意在匿名空间和全局空间放相同名字的变量。
此外,对于a来说,如果以上定义同时存在,会引发语法错误(二义性)。
另外还有几点:
1.namespace并非一声明成员就固定,可以增加成员。
namespace sp
{
int k;
}
namespace sp
{
int l;
}
此时sp中k和l都是存在的
2.namespace引用有传递性:
namespace sp
{
using namespace std;
}
如果使用了引用了sp,那么std也同时包括进来了(命名空间中允许using声明和using引用)
以上。