c++ 命名空间
目录
目录
目录
namespace的定义
代码演示
先使用全局域,再使用namespace定义出的域
命名空间中可以定义变量/函数/类型等
命名空间可以嵌套
namespace的使用
指定命名空间访问
using将命名空间中某个成员展开
展开命名空间中全部成员
在c++中,由于库中的一些函数可能会与我们所建立的变量,结构体等等相同,这样子就造成了命名冲突,当命名冲突时,函数便会报错,而因此去建立一些新的变量又容易极易混淆,因此应运而生了命名空间
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
printf("%d\n", rand);
return 0;
}
如上代码
rand与#include<stdlib.h>中的函数冲突
因此编译报错
如下图删除后可以正常运行
因此,命名空间很好的解决了这个问题
namespace的定义
定义命名空间,需要使用到namespace关键字
后面跟命名空间的名字,然后接一对{}中即可,{}中即为命名空间的成员
命名空间中可以定义变量/函数/类型等。
namespace本质是定义出一个域,这个域跟全局域各自独立
不同的域可以定义同名变量,所以下面的rand不在冲突了。
C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找一个变量/函数类
型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编
译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。
namespace只能定义在全局,当然他还可以嵌套定义。
项目工程中多文件中定义的同名namespace会认为是一个namespace,不会冲突。
C++标准库都放在一个叫std(standard)的命名空间中。
代码演示
先使用全局域,再使用namespace定义出的域
多说无益,直接用代码进行展示
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdio.h>
#include<stdlib.h>
namespace 仙海赤
{
int rand = 10;
}
int main()
{
// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
printf("%p\n", rand);
return 0;
}
当加入命名空间后,发现rand可以正常打印,不过为什么打印的结果是一堆数字呢?
其实很好理解,在c语言中我们就学习过,局部变量的优先级大于全局变量
而对于这个命名空间而言,无疑是一个数据的存储地方,当查找rand时,先找到库函数中的就很好理解了
也因此,打印出来的是函数的地址,并非rand的值
该输入形式为%p即可
此时又会有人问了
为什么在c++中仍然使用printf呢
其实对于c++而言,完全兼容c语言,因此,哪个使用顺手使用哪个就可以了
命名空间中可以定义变量/函数/类型等
namespace 仙海赤
{
int rand = 10;
struct II
{
int a = 10;
int arr[9];
};
int Add(int x,int y)
{
return x + y ;
}
}
并且无报错以及问题
命名空间可以嵌套
namespace 仙海赤
{
int rand = 10;
struct II
{
int a = 10;
int arr[9];
};
int Add(int x,int y)
{
return x + y ;
}
namespace 成员
{
int c = 10;
}
}
无报错,通过嵌套,可以将一个认为的每个人工作的部分相互划分
大大方便了办公
namespace的使用
编译查找一个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。
#include<stdio.h>
namespace bit
{
int a = 0;
int b = 1;
}
int main()
{
// 编译报错:error C2065: “a”: 未声明的标识符
printf("%d\n", a);
return 0;
}
这样子使用就会报错
解决办法;
指定命名空间访问,项目中推荐这种方式。
using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。
展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。
指定命名空间访问
// 指定命名空间访问
int main()
{
printf("%d\n", N::a);
return 0;
}
使用符号(命名空间)::(名字)
如果嵌套定义则
(命名空间)::(命名空间)::(名字)
using将命名空间中某个成员展开
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
若如此使用则会有较小的危险性
展开命名空间中全部成员
using namespce N;
int main()
{
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
有很大的危险性