命名空间
在C/C++中,变量、函数和类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
#include<stdio.h>#include<stdlib.h>intrand=10;intmain(){printf("%d\n",rand);return0;}// 编译后后报错:error C2365:"rand":重定义;// 报错重定义是因为在stdlib.h里面已经定义了一个rand,这里重复定义了
// 这是库冲突,也就是自己定义的名字和库里面的名字重复
//也有自己互相冲突比如两个人写同一个项目的不同模块最后一合并有命名冲突
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
2.1 命名空间定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
- 正常的命名空间定义
// xioayu是命名空间的名字,一般开发中是用项目名字做命名空间名。// 自己练习用自己名字缩写即可,如张三:zsnamespacebit{// 命名空间中可以定义变量/函数/类型intrand=10;intAdd(intleft,intright){returnleft+right;}structNode{structNode*next;intval;};}- 命名空间可以嵌套
// test.cppnamespaceN1{inta;intb;intAdd(intleft,intright){returnleft+right;}namespaceN2{intc;intd;intSub(intleft,intright){returnleft-right;}}}- 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
注意:一个命名空间就定义了一个新的作用域(也就是命名作用域),命名空间中的所有内容都局限于该命名空间中。
//命名空间域看起来和局部域很像,实际上不是一回事,命名空间域不影响生命周期。
2.2 命名空间使用
命名空间中成员该如何使用呢?比如:
namespacebit{// 命名空间中可以定义变量/函数/类型inta=0;intb=1;intAdd(intleft,intright){returnleft+right;}structNode{structNode*next;intval;};}// 这里没有分号intmain(){// 编译报错:error C2065:"a":未声明的标识符printf("%d\n",a);return0;}//我们可以看到当没有使用特殊方法的时候,命名空间里的变量是无法被外面使用的命名空间的使用有三种方式:
- 加命名空间名称及作用域限定符
intmain(){printf("%d\n",N::a);return0;}指定访问最推荐,风险最小。当要访问嵌套的命名空间里的变量的时候,依次在左边加上命名空间名就行。
- 使用using将命名空间中某个成员引入
usingN::b;intmain(){printf("%d\n",N::a);printf("%d\n",b);return0;}- 使用using namespace 命名空间名称 引入
usingnamespce N;intmain(){printf("%d\n",N::a);printf("%d\n",b);Add(10,20);return0;}这就是命名空间全部展开,这种方式是告诉编译器这个域可以搜索,当全局变量和被展开的命名空间里的变量名字一样的时候,编译器会不知道哪个错误,但是实际上他们不在一个域里面,并不是重定义错误。
注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此在日常练习中推荐使用<iostream.h>+std的方式。