引例
在学习之前我们首先了来看这样一个情形:
在c语言下,我们写了两个头文件:链表和顺序表的。我们会定义一个type(typedef int type)方便改变数据类型(比如将int改成char),来做到整体代换。
但是我们两个头文件里面都有type,我们又同时引用两个头文件,就会导致type重定义。而解决办法就要宏条件,所以很麻烦修改。
命名空间
那么我们今天学的东西就可以解决以上问题。
首先我们要了解一个基础知识,我们代码只会查看公共空间(全局,和局部),对于创建的空间是没有权限访问的
关键词 namespace
这个是命名空间的意思,因为我们在写代码的时候,定义的变量、函数、类都可能会相同,有报错的风险,所以我们就可以将他们放到不同的空间里面,将它面隔离开来。
我们看以下代码
这里有两个参数一样的add函数,系统肯定会报错,因为不知道用哪个,那么我们就可以将其中一个用命名空间包括起来
命名空间的创建
以上就是我们创建的命名空间叫dgj
这个空间里面有整形a,函数add
那么就只能访问下面的add和局部变量a。
如果我们要访问dgj里面的东西怎么办呢?
空间限定操作符 ::
我们只要在对于变量、函数、类之前加上“命名空间::”就可以限定空间了
我们之前的结果是
将代码改成
那么就会变成
另外对于一下函数我们如何访问全局变量a呢?
我们只要这样就行
如果::之前没有命名空间,那么就是指的全局空间。
标准命名空间
我们在引用官方头文件的时候,我们自己写的函数也有可能和官方函数有重名,那么我们的也有官方命名空间std(standard)来区分。自行观察我们就可以发现我们用到官方的cout和endl函数都必须要加std::它们不属于全局空间和局部空间,如果不加限定是访问不到的。
命名空间的合并性
我们写头文件一般有.h和.cpp两个文件,那么为了防止重名我们两个文件都要被命名空间括起来。
是不是要定义两个命名空间呢?不是,我们只要定义一个命名空间,编译器会自动把它当作整体。
那不然我们的官方头文件有很多,官方命名空间就不是一个std了。
在同一个文件里面也可以写多个相同名字的命名空间,也是当作一个命名空间
命名空间的展开
我们可能经常用某个命名空间,一直用“命名空间::”不是很方便,所以我们可以直接展开某个命名空间,那么接下来的代码的变量、函数、类就会优先使用这个命名空间的,除非用“命名空间::”指明是其他命名空间的。
语法就是(以std为例)
那么在下面的代码我们就会默认使用std命名空间的,里面的cout、endl也不需要用::来限定空间。
注意:这里的展开和我们头文件的展开是不同的,我们学过文件的编译链接就知道我们的头文件是在预编译展开成代码插入到我们的代码里面的。但是我们的命名空间并不是展开成什么代码,只是一种虚拟的展开。
单独展开命名空间里面的某一个变量、函数、类
但是我们直接展开一个比较大的命名空间,也是会有可能出现重定义的,特别是在以后的工作里面。所以我们可以只展开某个常用命名空间的某一个。
例如我们用dgj这个命名空间来举例:
那么下面的变量a就是优先使用命名空间dgj里面的东西。而出了这个以外的东西就不是默认使用的。
命名空间的嵌套
命名空间是可以在命名空间里面定义的,举例:
这个命名空间就有两个子命名空间。
如果要使用就是
或者只是用其中的一个
或者不展开,我们只是限制命名空间:
就是像剥洋葱一样一层一层向里。
类的命名空间举例
另外我这里举例类的相关例子:
这里的类也是一个对应的命名空间,那么我们可以限定空间来操作里面的变量、函数等。
命名空间的实际运用
例如一个公司要搞一个项目,然后项目肯定要分项目组,比如美术页面,底层逻辑等等,最后这些项目是要合到一起的。所以为了防止重定义,就让这几个项目组创建自己的命名空间例如A,B,C,D...
然后在项目A里面就会有很多人,为了防止这些人的命名重复导致重定义,那么每个人都会有一个命名空间,这里也体现了嵌套命名空间的意义。
那么通过上面的操作,我们就可以完美的避免合代码时出现重定义等相关错误。
看到最后了,觉得不错的就点个赞吧🙂