码字不易,养成习惯,先赞后看
命名空间
命名空间介绍
命名空间是C++为了解决C语言中命名冲突的缺陷而设计出来的一种语法。大致就是将变量名定义在一定的空间中,在使用时指定变量所在的域,帮助编译器明确地识别变量。借助这种特性,就可以在不同地命名空间中定义名字相同但是作用不同的变量。其次,C++还将库函数分装在自己的标准库中,所以我们也可以使用库函数的名字来定义适合的变量。我们所需要做的就是在使用定义在命名空间中的变量时进行作用域的指定,帮助编译器知道,我们在使用的具体是哪个命名空间中的变量。(后面会有具体的介绍以及示例)
如何定义命名空间?
在定义命名空间时,我们需要用到C++的一个关键字namespace
具体使用如下:
namespace UESTCer //namespace + 命名空间的名称(如:UESTCer)
{
char name[10]; //下面是命名空间域。
int age; //在命名空间域中定义你所需要的变量
char ID[20];
}
如何使用命名空间中的变量
在使用命名空间中的变量时,我们需要做的就是指定变量的作用域,即:变量在哪个定义域中定义。所用到的是域作用限定符: ::
具体使用如下:
namespace UESTCer //先定义一个命名空间
{
char name[10];
int age;
char ID[20];
}
int main()
{
UESTCer::age = 20; //命名空间名称::变量名
printf("%d", UESTCer::age);
return 0;
}
标准库及如何使用标准库中的内容
标准库中std也是一个命名空间的名称,是C++为了防止一些名称引起命名冲突的问题,把库里的内容分装到以std为名的命名空间中。
由于std也是一个命名空间,所以我们在使用时就不能直接使用,下面我会介绍三种常见使用方式
方法一:
//在每次使用库中内容时,都在名字前面加上域作用限定符
#include <iostream>
namespace UESTCer
{
int age;
char name[10];
}
int main()
{
UESTCer::age = 20;
std::cout << UESTCer::age << std::endl;//注意这一行cout\endl都是标准库里的内容
return 0; //age是UESTCer这个命名空间的变量,都要加::
}
方法二:
//直接将std这个命名空间全部打开,相当于直接把命名空间这个限制打破
namespace UESTCer
{
int age;
char name[10];
}
using namespace std; //using 命名空间名称 ——>直接打开整个
int main()
{
UESTCer::age = 24;
cout << UESTCer::age << endl; //在这里,我们就可以直接使用cout\endl了
return 0;
}
但是方法二有一个问题,命名空间被打破,相等于没有std这个命名空间,那么又回到了C语言的问题,会出现命名冲突的问题,相等于C++对于C缺陷的弥补你并没有去使用“一夜回到解放前”。所以这种方法虽然简单,但是它不规范,所以在正规的代码中,不建议采用这样的方式!
方法三:
//仅将经常使用的内容展开,方便直接使用,为展开的内容仍需要指定命名空间域
using std::cout;
using std::endl; //在这里将cout\endl提前展开,方便后面直接使用
//但是没有在std中没有被展开的内容无法
namespace UESTCer
{
int age;
char name[10];
}
using namespace std;
int main()
{
UESTCer::age = 24;
cout << UESTCer::age << endl; //所以在这里我们不需要std::,可以直接使用
return 0;
}
注意事项及补充
1、命名空间的使用,可以让我们使用与库函数相同的名称
例如:
scanf本身是一个库函数,但是在命名空间的参与下,scanf被限制在自己的命名空间中,没有去打开这个命名空间,那么scanf不会被认为是库函数,scanf可以成为一个自己决定内容的普通名称。
2、在使用一个变量名或者函数名时,首先编译器会在判断是否有::的指定作用域,若有,则该名称是该命名空间的内容,否则会默认在局部域或者全局域。同时,先去局部域寻找,再去全局域寻找
3、命名空间中,不仅可以定义变量,也可以定义函数,函数的使用方法同变量,也需要使用域作用限定符来限定作用域
4、可以在命名空间中嵌套定义命名空间,因为在一个大主题下可能有不同的小方向,而不同的方向极有可能有不同的变量和共同需要使用的变量,于是嵌套定义可以极好地完成这个任务
例如:
namespace UESTC
{
char schoolName[10]; //大命名空间
namespace classOne //大命名空间下的一个小命名空间
{
int number;
}
namespace classTwo //另一个小命名空间
{
char name;
}
}
嵌套调用方式
printf("%d",UESTC::classOne::number);
5、在同一个工程下的不同文件中,创建相同的命名空间,编译器会自动将相同名字的命名空间合并成一个但是要注意,两个同名命名空间中不能有相同的变量名,否则在合并时会出现重定义的报错!