命名空间的由来
在编译C语言的代码时,我们经常会遇到以下两种情况
1.重复定义变量名或函数名
这种情况一般通过在变量后加上数字来解决
2.与库函数变量冲突
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”
在我们日常进行测试的小工程中,往往变量都可以通过不断修改名称来避免重名,而在多人合作的大项目工程中,当所有人的项目最终合在一起时,我们便不可避免面对重名的问题,如果再重新修改其他人的命名,工程代价便会变得特别大,至此,C++便加入了命名空间来解决这一问题
命名空间的定义和访问
1.命名空间的定义
在命名空间中,我们每一个人所写的变量都会存在各自独特的命名空间(namespace)里,命名空间中的元素不会存在全局中,只有我们访问命名空间才会获取其中的元素,而定义我们的命名空间非常简单
我们只需要在namespace后加上自己需要命名的名称,便定义了一个命名空间,我们可以在空间中随意定义自己的元素
2.命名空间的访问
命名空间的访问有两种方式
1.单独访问
在C++中,我们会引入一个新的标识"::",用来表示访问命名空间的元素
![](https://i-blog.csdnimg.cn/blog_migrate/ffc2f999fdcebac61ab498263231d58c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6f0c7c4abc1f30f47e4ad01cc7edbe70.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1370223100e822bbd51172d105f457a1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9f798ff50b70000ead2a02c73bdfc7b9.png)
我们可以看到,在命名空间Ehundred后加上::我们便可以访问到命名空间的这一个元素
同时我们还可以访问函数,
但是需要注意的是,我们在访问结构体时需要在struct后再加上命名空间的名字
2.展开命名空间
通过上面访问命名空间的方法,我们可以写出以下程序
#include<iostream>
int main()
{
std::cout<<"hello world"<<std::endl;
return 0;
}
我们发现,当我们每次使用iostream库函数时,我们都需要在函数名前加上std::,不仅非常麻烦,而且会及其影响函数可读性,所以,我们往往会直接展开整个命名空间
using namespace的作用是,将一个命名空间的所有内容变成全局变量,即解除了namespace的限定,我们在使用最常用的<iostream>时,我们通常会直接展开整个std命名空间来使程序更简洁
3.展开部分命名空间
我们展开所有命名空间,便使程序更简洁更方便,但是,展开所有命名空间的风险也非常大,我们此时便可以只展开命名空间中单独的某一个经常使用的内容,这样既避免了命名冲突带来的风险,也使程序更简洁
在使用了std::cout后,cout便变成了全局变量,而endl仍在命名空间的限制中无法访问
命名空间的注意点和细节
1.命名空间可以自动合并
我们如果重复定义一个变量,编译器便会报错,而如果我们重复定义了多个命名空间,命名空间会冲突吗?
我们发现,编译器并没有报错,因为编译器会自动合并相同名称的命名空间,此时我们只需要避免和他人的命名空间重名便可
此时我们要注意:不要在相同的命名空间重复定义一个变量
2.命名空间可以在函数内部展开
如果我们需要在某一个函数中大量使用某一个命名空间,而又不想让他成为全局变量,我们可以在函数内部展开命名空间