<一>命名空间的由来
我们在学习C语言的阶段我们,内置的一些函数,关键字等等都是大量存在的。这些我们创建的函数,变量都将存在于全局变量中可能会导致很多冲突,如下面的例子。
#include<stdio.h>
#include<stdlib.h>//stdlib库里面存在一个rand函数
//在C语言中就会涉及到这方面的名字冲突的问题
//所以c++在就提出了namespace 命名空间来解决这个问题
int rand = 0;
int main()
{
printf("%d", rand);//这里打印的是 rand函数的地址
return 0;
}
使用命名空间对标识符进行本地化处理,以避免命名冲突或者名字的污染。
<二>定义
定义命名空间需要使用命名空间关键字namespace。后面跟上命名空间的名字,然后接一对{}即可,{}内部为命名空间的成员。
1.正常的定义
namespace test
{
//命名空间可以定义变量,函数,类型
int rand = 0;//这里可以初始化也可以不用初始化
rand本质上还是一个全局变量
//但是放在命名空间里面了,相当于在rand外面加上了一个墙
//改变了访问规则
int Add(int x, int y)
{
return x + y;
}
struct Node
{
struct Node* next;
int size;
};
}
2.命名空间可以嵌套
namespace test
{
int rand = 0;
int Add(int x, int y)
{
return x + y;
}
struct Node
{
struct Node* next;
int size;
};
namespace test2
{
int a;
int b;
int sub(int x, int y)
{
return x - y;
}
}
}
3.命名空间的合成
相同的名字的命名空间(无论在那个文件下,只要在一个项目中),编译器在最后会合成一个命名空间。例如上面的两个命名空间最后就会合成同一个命名空间(只要在一个项目中)。
注意:
- 在c++的官方库中就是使用了这个原理将全部的函数名称都合成到一个命名空间中,这个命名空间就是std。
- 命名空间域里面的所有成员都定义在静态区,都是全局变量。只有定义在函数内部的变量才是局部变量(存在栈中)。
- 命名空间不会影响成员的生命周期,只是限定域,只影响查找规则。
- 在c++中变量的查找,一般是现在局部找,然后在全局找,如果不指定命名空间域不会命名空间域里面找。
- 一个命名空间定义了一个新的作用域,命名空间中所有的内容都局限于改命名空间域中
<三>使用
使用命名空间就需要一个操作符 ' :: ',域作用限定符。 格式”命名空间名字 :: 成员“。
1,加命名空间名称
namespace test
{
int a = 10;
int b = 100;
}
int main()
{
printf("%d", test::a);
return 0;
}
2,使用using将,命名空间部分展开
namespace test
{
int a = 10;
int b = 100;
}
using test::a;
int main()
{
printf("%d", a);
printf("%d", test::b);
return 0;
}
3.使用using将命名空间全部展开
namespace test
{
int a = 10;
int b = 100;
}
using namespace test;
int main()
{
printf("%d", a);
printf("%d", b);
return 0;
}
注意:
- 访问结构体成员的时候会使用 struct test::Node,注意test的位置。
- 建议日常练习的时候将全部展开 ,在写项目的时候就不要将其全部展开了
<四>using namespace std;
这里的std就是c++标准库的命名空间,c++将标准库的定义实现都放在了这个命名空间里面。using namespace std;就是将其全部展开(无访问限制)。个人建议练习时候这样做。写项目的时候不要全部展开,可以将常用的展开即可。