目录
如何理解命名空间
在解释何为命名空间之前我先阐述一段简要,在C语言的使用和学习中有一个不可避免的问题命名冲突即相同的域里面无法定义重名的变量、函数、类型,等等什么又是域呢?它与我们学习到底作用域有和关系呢?
对于域最简单的理解是区域和范围,在c语言中有两种域全局域和局部域,全局域的范围是整个程序而局部域的范围仅在大括号{}内,域和作用域关系的理解是:某个变量只能在它所在的域里面访问和使用。
a变量所在的域是F1函数的{}内所以它们的作用域范围也在F1的{}函数内,无法在其他域中使用和访问a变量,所以main里才无法调用a变量,编译器报告的错误是没有找到a变量。
理解什么是域后我们在回到命名冲突的问题上,一个域里面不能有重名的“方法”,但不同域之间却可以有相同名的“方法”,所以c++解决命名冲突的方案是创建一个自己的域即命名空间域,我们可以通过命名空间关键字来创建命名空间域这样就可以和别的域区分开来从而避免命名冲突。
- 方法指的是:变量、函数、类型
命名空间域就相当于在全局域里面划分出一块单独的域来使用并通过为这块域取名字来标识这块域。这块区域本质还是这块大空间(全局域)的一部分,不同的是当你需要访问和使用某个命名空间的一个变量时,你就需要知道它是大空间里的那一块命名空间才能访问这个变量。这就解决了命名冲突的问题同时又不需要在原有的基础上做出一些较大的改变。
命名空间域的创建
使用到namespace关键字,后面跟命名空间域的名字,然后接一对{}即可,{}中即为命名空间的成员,成员可以是变量、函数、类等等。
namespace zhl
{
int rand = 10;
Add(int left, int right)
{
return left + right;
}
}
使用细节:
- 命名空间{}里面就是命名空间域
- zhl是该名命空间域的姓名
- 命名空间域的成员可以是变量、函数、类型、类等
- 命名空间域里面可以嵌套命名空间域
- 同一工程内可以存在多个相同的名称的命名空间,但编译器最后会将这些同名的命名空间合并同一个命名空间
- 一个命名空间域就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
命名空间域的访问
在介绍命名空间域之前先介绍一个c++操作符,: (域限定符)它能功能是可以让编译器去指定的域里进行搜索。编译器的默认搜索规则是局部域大于全局域(命名空间则需要指定搜索),所以当局部变量和全局变量命名冲突时会优先使用局部变量,如果这时想使用全局变量的话可以在变量前加上域限定符,这样编译器就只会去全局域里面进行搜索了。
int b = 1;
int main()
{
int b = 2;
printf("%d\n", ::b); //::前面是空白就表示去全局域里面搜索
return 0;
}
使用细节:
- xxx::(域限定符),::前面的xxx就表示指定去xxx域里面搜索
- ::(域限定符),::前面是空白就表示指定去全局域里面搜索
- 在使用域限定符到指定域里面搜索时就只会在该域里面进行搜索
命名空间域的访问方式
命名空间的成员不会被编译器主动访问,想要访问命名空间域有以下三种方法
- 全部展开
- 指定展开
- 指定访问
全部展开
使用using关键字将命名空间展开,命名空间展开的意思是:将命名空间成员暴露在全局中,所以在展开只会就可以使用访问全局成员的方式来访问命名空间成员
namespace zhl
{
int a = 1;
int b = 9;
}
using namespace zhl;//全部展开
int main()
{
printf("%d\n",a);
return 0;
}
指定展开
也可以使用using关键字指定展开某个成员,需要使用域限定符告诉编译器要展开的成员是那个命名空间域中的
namespace zhl
{
int a = 1;
int b = 9;
}
using zhl::a; //指定将a展开
int main()
{
printf("%d\n",a);
return 0;
}
要注意的是命名空间展开后就意味着,将命名空间的成员暴露在全局中,也就说可以这时命名空间成员的访问规则与全局成员一样,访问规则一样就无法区分全局成员与命名空间成员,所以将命名空间展开后必须保证命名空间成员与全局成员没有重名,否则编译器会报错。
指定访问
命名空间名+域限定符+成员名,可以使用域限定符让编译器去指定的命名空间域去搜索。
namespace zhl
{
int a = 1;
int b = 9;
}
int main()
{
printf("%d\n",zhl::a);//指定访问
return 0;
}
总结
- 相同的域里面无法定义重名的变量、函数、类型,但不的同域之间可以定义重名的变量、函数、类型
- 命名空间是C++用来解决C语言命名冲突的方案,通过创建一个自己的命名空间域来与其他的域区分开从而避免命名冲突
- ::(域限定符)可以让编译器去指定的域里面进行搜索,::前面是空白就表示去全局域里面搜索
- 命名空间的访问方式有三种:将命名空间全部展开,将命名空间部分展开,使用域限定符指定去命名空间里面搜索
- 命名空间展开的意思是:将命名空间的成员暴露在全局中,同时表示这时命名空间成员和全局成的访问规则一样,访问规则一样就必须保证命名空间成员与全局成员没有重名否则编译器会报错
为了添加封面而添加的封面