详解c++关键字。namespace命名空间的用法。实际开发中namespace应用场景。

namespace 命名空间

要介绍namespace就先要讲明白c语言域的概念

什么是域呢?域就是变量作用的空间,在c++中,域被分为全局作用域和局部作用域。
在这里插入图片描述
一个域中的变量不能重名。不同域之间的变量可以重名

变量的调用顺序

#include <stdio.h>
int a = 0;

int main(){
	int a = 100;
	printf("%d", a);
}

在这个代码中,我们打印变量a,结果是100,这是因为在访问变量的过程中,先调用自己所在域的,如果没有才访问域外面的。
比如如下代码
在这里插入图片描述
打印出100,和110,这就是变量的访问顺序,先在自己所在域查找,自己的域中没有的再向上一层查找。
那么我们想在局部作用域里调用作用里调用全局作用域的变量,比如在上述代码中打印a得到0要如何实现呢?这就引入了我们所说域作用限定符

域作用限定符

:: //这个就是域作用限定符
A::B // 表示在A作用域下的B变量
::B// 如果前面为空,表示全局作用域下的B变量

在这里插入图片描述
在这里插入图片描述
可以看到我们通过域作用限定符成功访问到了全局作用域里的变量a。

命名冲突

c++的语法产生是为了解决c语言的不足。我们学习c++要从这个角度学起。
c语言是有命名冲突的问题,比如我们引入了一个头文件,这个头文件里有一个名叫rand的函数,那么我们自己的程序里就不能有和他同名的函数,不然会报错。就是c语言的变量命名不能和库中的命名冲突!
在这里插入图片描述
在这里插入图片描述
出现这种情况是因为我们在调用一个库的时候,本质上是相当于把这个库复制到全局作用域之中,在这个库里本来就有rand这个函数,他也随着调用被复制到全局作用域下。
当我们定义rand变量时,他和库里的函数同名了,这样我们在调用rand时,编译器会不知道我们调用的是哪一个rand,因此就会报错。
同一个作用域里不能有同名的变量或函数这里全局域下就有变量和函数同名了。
但是随着我们的工作量逐渐变大,重名的情况不可避免,于是c++引入了命名空间这个概念。

namespace

命名空间是为了解决命名冲突问题而诞生的,他可以解决上述的:全局变量和库函数重名的问题。
在这里插入图片描述
我们自定义一个命名空间,把同名的rand放进去,再执行编译,发现编译通过没有报错。
对于namespace我们可以这样理解:相当于重新申请了一个域,域里面放的东西独立于全局作用域下,因此不会和库冲突。在实际运行里我们也可以通过采用某种方法在局部作用域里调用它,实现其在全局作用域的功能。
因此命名空间里可以存放的东西有:

  1. 变量
  2. 函数
  3. 结构体
    在实际开发里,可以给每一个开发者一个自己的命名空间,在访问时从自己的命名空间里访问变量,就解决了命名冲突的问题

访问命名空间

我们可以使用域作用限定符来访问命名空间里的变量。

在这里插入图片描述
第一个rand打印的是被放在全局作用域里的rand()函数地址,第二个但因的是mySpace命名空间下的rand变量的十六进制那个
在这里插入图片描述
结果如图,10转化为10进制正好是A;

命名空间的嵌套

实际开发中,一个大项目可以分为多个小项目,每个小项目又能再分成多个小组来完成,每个小项目独占命名空间,因此命名空间内也可以创建命名空间。
在这里插入图片描述
但是在嵌套之后,我们不能直接用内层的命名空间名来访问内部的变量,必须由外到内访问。
在这里插入图片描述

同名空间的合并

在一个工程(project)里的的同名空间会进行合并
在这里插入图片描述
比如我们List.h命名了一个mySpace。Stack.h里命名了一个mySpace,这样在运行时会把他们合并。
那如果合并后再发生冲突怎么办呢?
在这里插入图片描述
合并后还会发生冲突,就可以采用前面讲过的命名空间嵌套来进一步解决冲突。
在这里插入图片描述
这样子合并后就不会冲突了。
但是我们在调用它的时候
在这里插入图片描述
每一次调用都要用域作用限定符来寻找,这样子就很麻烦,于是我们引入了using namespace这一操作。

using namespace

用这个相当于把一个命名空间给打开,展开后的命名空间就相当于把合并后的给放到全局作用域中。

在这里插入图片描述

using space 展开出现问题

在这里插入图片描述
当我们命名空间里有一个a,同时在外界也有一个a,当我们把命名空间展开后,相当于命名空间直接放到了全局作用域里,就会指代不明。

在这里插入图片描述
不展开的话就不会出现这些问题。
所以我们要理解展开的实质,并且合理利用它。但是如果真的要化简代码呢?于是我们引入的单独展开。

单独展开

在这里插入图片描述
这时候我们只把mySpace里的List给展开,不把a给放出来,也就不会报错。

using namespace std

这一行代码我们很常见,std封c++库的命名空间,相当于一个写好的头文件,我们要想用c++库里的一些东西又不想手动用作用域控制符的话,就可以用这个代码来方便使用。
但是同样也会有冲突的风险。
在这里插入图片描述
所以我们要根据需要放出来一些我们需要避免冲突的东西。

总结

  1. 命名空间解决了命名冲突的问题
  2. 命名空间里可以创建变量,函数,结构体
  3. 命名空间可以嵌套
  4. 同一工程里相同名字的命名空间会合并,可利用嵌套解决合并后冲突问题
  5. 命名空间只能放在全局
  6. 命名空间展开相当于放到全局作用域
  7. 直接展开会再次发生命名冲突
  8. 用什么展开什么。(放某一个)
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值