1、为什么要有命名空间
C++中引入命名空间是为了解决在C语言中留下的命名冲突问题,补充C语言的不足,在C/C++中,变量、函数和类都是大量存在的,都存在于全局作用域中,可能会导致很多冲突。所以使用命名空间是对标识符的名称进行本地化,来避免命名冲突或名字污染。
样例:
#include<iostream>
namespace N1
{
int a = 1;
}
namespace N2
{
int a = 2;
}
int main()
{
int a = 3;
printf("N1::a=%d\n", N1::a);
printf("N2::a=%d\n", N2::a);
printf("a=%d\n", a);
}
上面定义了两个命名空间,各自都有相同的局部变量a,如果没有指定某个命名空间域,很容易出现命名冲突。a查找顺序会先从局部域到全局域再到展开的域中去找,指定某个域能够很快找到。
2、命名空间的使用
2.1命名空间的定义
定义命名空间,需要使用namespace关键字,后面跟上命名空间的名字,命名空间的成员可以有定义变量,定义函数,结构体类型等。
// 1. 正常的命名空间定义
namespace hx
{
// 命名空间中可以定义变量/函数/类型
int rand = 10;
int Add(int left, int right)
{
return left + right;
}
struct TreeNode
{
struct TreeNode* left;
struct TreeNode* right;
};
}
//2. 命名空间可以嵌套
namespace N1
{
int a;
int b;
int Add(int left, int right)
{
return left + right;
}
namespace N2
{
int c;
int d;
int Sub(int left, int right)
{
return left - right;
}
}
}
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace N1
{
int Mul(int left, int right)
{
return left * right;
}
}
2.2命名空间的使用
namespace N1
{
int a = 0;
}
int main()
{
// 编译报错:error C2065: “a”: 未声明的标识符
printf("%d\n", a);
printf("%d\n",N1::a);
return 0;
}
这里可以使用作用域限定符::来指定某个命名空间
3、using namespace std
3.1 using namespace std 是什么?
在C++中编写代码,会经常使用using namespace std,它可以方便调用命名空间std内的定义的所有标识符,代码看起来更简洁易读。
3.2 using namespace std 的意义?
C++为了防止名字冲突,把标准库中的东西都放入到std命名空间中,std是C++标准库的命名空间
好处:定义跟库中名字相同的东西不会产生冲突,都在各自的命名空间中
坏处:直接展开会把命名空间全部暴露出来,库中的数据也就暴露出来了
4、命名空间的三种展开方式
4.1、加命名空间名称及作用域限定符(指定访问命名空间)
int main()
{
printf("%d\n", N::a);
return 0;
}
4.2、使用using将命名空间中成员引入(展开常用的,不暴露整个命名空间)
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
4.3、使用using namespace命名空间成员引入(命名空间全部展开)
using namespce N;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
5、推荐using namespace std使用方式
1、在项目中,尽量不使用using namespace std。
2、平常练习代码可以使用using namespace std。
3、在平常的项目中可以指定命名空间访问+展开常用的
例如:要定义一个vector 可以指定命名空间访问,比如cout,cin这些频繁使用的语句,可以直接using std::cout,using std::cin直接展开。