我们在C++程序中总是看到这一行代码
#include<iostream>
using namespace std;
那using namespace std;表示的是什么意思呢?
命名空间解决的问题
在C语言中,经常会出现命名冲突的问题
如下代码
#include<stdio.h>
int rand = 0;
int main()
{
printf("%d", rand);
return 0;
}
运行当前代码没有任何问题
但是如果再包含一个头文件
#include<stdio.h>
#include<stdlib.h>
int rand = 0;
int main()
{
printf("%d", rand);
return 0;
}
在这里报错显示rand重定义。这是因为再头文件"stdlib.h"中已经定义了一个名为rand的函数,所以导致了命名冲突。
C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
命名空间的定义
正常命名空间的定义
namespace <名称>
{
}
#include<stdio.h>
#include<stdlib.h>
namespace xxx
{
int rand = 0;
}
int main()
{
printf("%p", rand);
return 0;
}
命名空间的嵌套
namespace xxx
{
int rand = 10;
namespace yyy
{
int rand = 20;
}
}
int main()
{
printf("%d", xxx::rand);
printf("%d", xxx::yyy::rand);
return 0;
}
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
命名空间可以定义成相同的名字,调用时会将同名的命名空间合并
ps:同名的命名空间内部定义的数据不能同名,会导致重定义
命名空间成员的调用
加上了命名空间之后,就解决了命名冲突的问题,这里一个rand是头文件里面包含的函数,另一个是在命名空间里面定义的一个整形变量,这里编译器默认调用的是头文件的rand函数。如果我们要调用命名空间里面定义的rand要怎么办呢?
这里要使用域作用限定符 <命名空间> : :<空间内定义的标识符>
namespace xxx
{
int rand = 1;
}
int main()
{
printf("%d", xxx::rand);
}
命名空间中可定义的类型
命名空间中可以定义变量/函数/类型
namespace xxx
{
int rand = 10;
void Add(int a, int b)
{
printf("%d", a + b);
}
struct Node
{
struct Node* next;
int val;
};
}
int main()
{
printf("%d", xxx::rand);
xxx::Add(1, 2);
struct xxx:: Node node;
return 0;
}
命名空间的展开
全部展开(授权)
using namespace <名称>;
namespace xxx
{
int a = 10;
int b = 20;
}
using namespace xxx;
int main()
{
printf("%d\n", a);
printf("%d", b);
return 0;
}
可以访问命名空间xxx中的所有成员
但是全部展开是一种不安全的方式
例如:
namespace xxx
{
int rand = 10;
int a = 20;
}
using namespace xxx;
int main()
{
printf("%d\n", rand);
printf("%d", a);
return 0;
}
编译器会报错,不明确的符号,可能是头文件中包含得到rand函数,也可能是命名空间xxx内部的,只能再次利用域作用限定符。我们可以用部分展开的方法
部分展开(授权)
using <名称> : :<成员>;
namespace xxx
{
int rand = 10;
int a = 20;
}
using xxx::a;
int main()
{
printf("%d\n", rand);
printf("%d\n", xxx::rand);
printf("%d", a);
return 0;
}
这里只展开了命名空间xxx中的a变量,所以main函数中不能直接访问xxx中的rand变量,printf("%d\n", rand);中访问的是头文件中包含的rand函数,printf("%d\n", xxx::rand);才是xxx命名空间中的rand函数,而a变量由于展开了,可以直接访问