一、namespace的价值
在C/C++中变量、函数、类等都是大量存在的,这些变量、函数和类的名称都存在于全局作用域中,可能会导致冲突。
为了避免这些冲突的产生所以我们使用namespace这种命名空间来对标识符的名称进行本地化。
我们来看下面这段代码:
#include<stdio.h>
#include<stdlib.h>int rand = 10;int main()
{printf("%d ", rand);return 0;
}
error C2365: “rand”: 重定义;以前的定义是“函数”
在这里报出了一个错误,“rand”重定义,以前的定义是“函数” 就是因为所在空间的原因造成的,rand是一个全局的变量,在这个文件中引入了rand这个函数,那么他就会因为同样的的名字造成重定义的错误。要解决这样的情况就需要使用命名空间来进行处理,
二、namespace的定义
定义命名空间,需要使用namespace关键字,后面跟命名空间的名字,然后介意对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量、函数、类型等。
namespace的本质是定义出一个域,这个域和全局域各自独立,不同的域可以定义同名变量,所以我们来看下面的rand不再冲突了:
namespace XL
{int rand = 10;
}int main()
{printf("%d ", XL::rand);return 0;
}
在这里不会出现任何的冲突,此时就解决了变量、函数、类等定义过多导致的命名冲突问题。
C++中有函数局部域、全局域、命名空间域、类域;域的存在会影响编译器编译时查找对应的变量、函数等的逻辑,而且局部域和全局域还会影响变量的生命周期,命名空间域和类域不影响变量的生命周期。
1、namespace定义的命名空间可以定义多种类型的数据:
namespace XL
{int rand = 10;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}
}
2、命名空间是可以嵌套的
namespace XL
{int rand = 10;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}namespace XLL{int rand = 100;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}}
}
在这个嵌套的空间中我们可以定义名称相同的变量、函数、结构体等,并不会出现任何问题。
3、命名空间在不同的文件中定义相同的空间名,编译器会默认他们是在同一个域中
我们来看下面这段代码:
//test.h
#include<stdio.h>
#include<stdlib.h>namespace XL
{int rand = 10;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}
}//test.cpp
#include"test.h"namespace XL
{int rand_copy = rand;
}int main()
{printf("%d ", XL::rand_copy);return 0;
}
在这里我们在别的文件中使用头文件中定义的数据是可以正常使用的,也就说明了在这里,被命名空间只要名字相同定义的变量在其他文件中同样可以被访问。
三、命名空间的使用
编译查找一个变量的定义/声明时,默认只会在局部或者全局查找,所以我们直接对命名空间中的数据进行访问会导致程序报错,我们可以使用下面这几种方式来进行访问:
方式一:
namespace XL
{int rand = 10;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}
}int main()
{//指定命名空间的访问,在项目中我们也推荐使用这种用法printf("%d ", XL::rand);return 0;
}
方式二:
namespace XL
{int rand = 10;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}
}指定命名空间的访问,在项目中我们也推荐使用这种用法
//int main()
//{
// printf("%d ", XL::rand);
// return 0;
//}//using将命名空间中的成员展开,项目中经常访问的不存在冲突的成员推荐这中方式
using XL::rand;int main()
{printf("%d ", rand);return 0;
}
方式三:
namespace XL
{int rand = 10;int n = 10;struct XLs{int s;char c;};int Add(int x, int y){return x + y;}
}// 展开命名空间中的所有成员,不推荐在项目中使用
// 并且即使展开了,有冲突的数据还是可能报错,但仅在联系中使用是可以的
using namespace XL;int main()
{printf("%d ", n);return 0;
}