目录
一、定义
二、使用
三、注意事项
一、定义
定义:
无名命名空间,又称为未命名的命名空间。是指关键字namespace后紧跟花括号括起来的一系列声明语句,不需要对命名空间取名。
eg:
namespace {
int a = 10;
int get(void)
{
return 20;
}
}
生命周期:
无名命名空间中定义的变量拥有同静态变量一样的生命周期,在第一次使用前创建,直到程序结束才销毁。
作用域:
无名命名空间中定义的成员的作用域与该命名空间所在的作用域相同。比如,如果在某个源文件中定义无名命名空间,则该无名命名空间只在该源文件能访问。
二、使用
用法:
无名命名空间的成员可以在所定义的文件中直接使用。不需要使用命名空间的名字进行作用域限定,因为无名命名空间没有名字可以用来限定。
eg:
#include <iostream>
using namespace std;
namespace {
int a = 10;
int get(void)
{
return 20;
}
}
int main(void){
cout<<"a: "<<a<<endl;
cout<<"get(): "<<get()<<endl;
return 0;
}
优点:
使用无名命名空间可以替代文件中的静态声明。在文件中进行静态声明的做法已经被C++标准取消,推荐的做法是使用无名命名空间。
将文件中的变量和函数声明为静态声明,可将其作用域限定为该文件范围有效,避免与其它文件的同名变量或函数冲突。在C++引入无名命名空间后,在文件中使用无名命名空间来定义变量和函数,也能起到与静态声明一样的效果,而且不需要每个变量和函数单独加static进行声明。
三、注意事项
1、如果两个源文件都含有无名命名空间,这两个无名命名空间可以定义相同名字的成员,因为这两个空间没有关联,各自空间的成员作用域也仅限于各自文件中。
2、无名命名空间的成员名称不能与全局作用域的成员名称相同,会导致二义性。
eg:
#include <iostream>
using namespace std;
int a = 10;
namespace {
int a = 10; //错误,会与全局数据区的a冲突
int get(void)
{
return 20;
}
}
int main(void){
cout<<"a: "<<a<<endl; //二义性,不知访问哪个a,编译报错
cout<<"get(): "<<get()<<endl;
return 0;
}
3、与所有命名空间类似,一个无名命名空间也能嵌套在其它命名空间中。此时,无名命名空间的成员可以通过上一层命名空间的名字来访问。
eg:
#include <iostream>
using namespace std;
namespace local{
namespace {
int a = 10;
int get(void)
{
return 20;
}
}
}
int main(void){
cout<<"a: "<<local::a<<endl;
cout<<"get(): "<<local::get()<<endl;
return 0;
}
4、一个源文件可以定义多个无名命名空间,但是这些空间内的成员名称不能相同,否则会导致二义性。
eg:
#include <iostream>
using namespace std;
namespace {
int a = 10;
int get(void)
{
return 20;
}
}
namespace {
int a = 13; //错误,会与前面空间的a冲突,编译报错
int b = 18;
int getb(void)
{
return 28;
}
}
int main(void){
cout<<"a: "<<a<<endl;
cout<<"get(): "<<get()<<endl;
cout<<"b: "<<b<<endl;
cout<<"getb(): "<<getb()<<endl;
return 0;
}
参考文献:
《C++ Primer中文版》