目录
a. 加命名空间名称及作用域限定符(在项目编写的时候推荐使用)
b.使用using将命名空间中某个成员引入(在项目编写的时候推荐使用)
一.C语言的缺陷
我们都知道C++其实是对C语言的升级和一些问题的修正,关于C++中的命名空间其实是对于C语言中的问题进行修正,具体修正的问题我们通过一个例子来进行体会。
#include <stdio.h>
//#include <stdlib.h>
int rand = 0;
int main(void)
{
printf("%d", rand);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int rand = 0;
int main(void)
{
printf("%d", rand);
return 0;
}
通过观察上面的两段代码,我们发现两段代码只是差在一个头文件上,但是两端代码有没有上面明显的语法错误,但是当我们放到编译器中运行时,它会发出这样的警告:
编译器提示我们这里的rand 变量被重定义了,可是在我们的代码中只有一个rand变量的显示定义,哪里来的重定义啊,这时因为第一段代码可以完美运行,那么问题一定出在第二段代码新引入的stdlib头文件中,其实在这个头文件中,存在一个rand变量是已经在库中定义好的。
那么这样就暴露了一个C语言中非常令人头疼的问题,我写的每一行代码都满足C语言的标准规定,但是却存在命名冲突的问题,这个例子中的问题很好改正,因为我们改变不了库中定义好的,那么我们只需要将我们定义好的rand改了,问题解决出院!
但是先别急,如果我们的代码很长,而且我们是在升级功能时遇到这样的状况,又如果我们是在协同工作时和我们的同事发生这样的事情怎么办,可以说可以协商一下嘛,其中一个人改一下喽!你知不知道你在说什么,好几万行代码,谁想改啊,打一架,好家伙互联网打架公司是吧!
哎!暴力是我们最不推荐解决方法的问题,所以我就向你推荐一个可以在编写代码初期就可以避免这样情况的方法----命名空间
总结:
C语言中存在的命名冲突的问题
1.和C语言标准库中的定义冲突。
2.在编写项目时,项目组成员之间可能会有命名冲突的问题。
二.什么是命名空间以及命名空间的定义
1.什么是命名空间
在C语言中我们都知道在相同的作用域下不可以定义同名的变量,那么此时我们想解决相同作用域中的同名变量的问题,此时就应该想到引入新的作用域,此时我们的问题就的到了解决。
那么该新的作用域就是-命名空间。
所以命名空间本质上解决的问题是在全局域中出现同名变量的问题。
2.命名空间的定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
#include <stdio.h>
#include <stdlib.h>
namespace rand_namespace
{
int rand = 0;
}
int main(void)
{
printf("%d", rand);
return 0;
}
此时我们上面遇到问题就解决了。
但是我们运行代码的结果是:
很明显我们使用的库中的rand,那么我们如何才能使用我们定义的命名空间中的rand呢?
其实呢命名空间本身上就是一个域,我们知道域有去改变一个变量的生命周期和访问权限的功能,所以命名空间呢也正是利用这一点对我们定义的变量进行分类。我们的代码先从局部域中搜索然后在从全局域中搜索,如果我们不指定命名空间域系统是不会自动去命名空间域中搜索的。那么现在我们的变量被一个叫命名空间的域给围起来了,那么我就需要一个钥匙打开它 这个钥匙就是
3.命名空间的使用
a. 加命名空间名称及作用域限定符(在项目编写的时候推荐使用)
int main()
{
printf("%d\n", N::a);
return 0;
}
b.使用using将命名空间中某个成员引入(在项目编写的时候推荐使用)
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
c.使用using namespace 命名空间名称 引入
using namespce N;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
Add(10, 20);
return 0;
}
注意这种方式并不是很推荐,因为此时使用的引入方式是直接将命名空间中定义的内容全部引入到全局作用域中那么和上面我们产生问题的原因不就类似了,此时就像坝放水一样,要一点一点的放,需要的时候在放,不管需不需要一下子全放了,是很危险的,我们是为了避免问题,这样的做法是有可能解决不了问题的,一般在程序开发是时候我们是推荐使用第一个和第二个方法并用开发的。
4.对于C++中为什么不使用.h头文件的解释
#include <iostream>
using namespace std;
int main(void)
{
int a = 10;
cout << a << endl;
return 0;
}
因为C++就在C语言的基础上升级出来的,很多C语言中的用法C++都是支持的包括引入头文件的方式,在早期的C++中是支持.h的头文件的引入方式的,但是在引入命名空间的概念后,C++将库中的内容都放到了std这个命名空间中,然后使用新的引入头文件的方式。但是C++还是支持以前的引入方式的。
在上面的代码中cout是流插入对象,在使用cout来打印程序中的内容时要使用<<流插入运算符。
C语言中printfC++也是支持的,但是cout在打印变量的时候会自己检查变量的类型,此时就不用我们指定了,但是就是因为这个检查的过程使得cout在效率上稍微低于printf。
cin是流提取对象,在使用cin来从键盘中获取数据的时候,要配合使用>>流提取运算符。
ps:
1.命名空间中可以定义变量/函数/类型。
2. 命名空间可以嵌套。
嵌套命名空间展开:N::n::rand
3.同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。