我们都清楚在C语言中,存在局部优先规则,如下:
int a = 0; //全局域
int main()
{
int a = 1; //局部域
printf("%d\n", a); // 1 局部优先
return 0;
}
我们都清楚这里的结果是1,但是如若我非要打印全局域里的a呢?
这里引出域作用限定符 ( :: ),效果如下:
加上了( :: ) ,此时访问的a,就是全局域,这里是全局域的原因是“ ::”的前面是空白,如若是空白,那么访问的就是全局域,这么看的话,我在“ ::”前面换成命名空间域,不就可以访问命名空间域里的内容了吗。其实“ ::”就是命名空间使用的一种方式。
比如我们定义了如下的命名空间:
namespace n1
{
int f = 0;
int rand = 0;
}
现在该如何访问命名空间域里的内容呢?其实有3种方法:
加命名空间名称及作用域限定符“ ::”使用using namespace 命名空间名称全部展开使用using将命名空间中成员部分展开
1、加命名空间及作用域限定符“ ::”
int main()
{
printf("%d\n", n1::f); //0
printf("%d\n", n1::rand);//0
return 0;
}
为了防止定义相同的变量或类型,我们可以定义多个命名空间来避免
namespace ret
{
struct ListNode
{
int val;
struct ListNode* next;
};
}
namespace tmp
{
struct ListNode
{
int val;
struct ListNode* next;
};
struct QueueNode
{
int val;
struct QueueNode* next;
};
}
当我们要使用它们时,如下:
int main()
{
struct ret::ListNode* n1 = NULL;
struct tmp::ListNode* n2 = NULL;
return 0;
}
针对命名空间的嵌套,如下:
可以这样进行访问:
int main()
{
struct tx::List::Node* n1; //访问List.h文件中的Node
struct tx::Queue::Node* n2;//访问Queue.h文件中的Node
}
但是上述访问的方式有点过于麻烦,可不可以省略些重复的呢?比如不写tx::,这里就引出命名空间访问的第二种方法:
2、使用using namespace 命名空间名称全部展开
using namespace tx;
这句话的意思是把 tx 这个命名空间定义的东西放出来,所以我们就可这样访问:
int main()
{
struct List::Node* n1; //访问List.h文件中的Node
struct Queue::Node* n2;//访问Queue.h文件中的Node
}
当然,我还可以再拆一层,如下:
using namespace tx;
using namespace List;
int main()
{
struct Node* n1; //访问List.h文件中的Node
struct Queue::Node* n2;//访问Queue.h文件中的Node
}
展开时要注意tx和List的顺序不能颠倒
这种访问方式是可以达到简化效果,但是也会存在一定风险:命名空间全部释放又重新回到命名冲突。
所以针对某些特定会出现命名冲突问题的,需要单独讨论:
(重点,后期常用)由此我们得知:全部展开并不好,我们需要按需索取,用什么展开什么,由此引出第三种使用方法
3、使用using将命名空间中成员展开
针对上述代码,我们只放f出来
namespace n1
{
int f = 0;
int rand = 0;
}
using n1::f;
int main()
{
f += 2;
printf("%d\n", f);
n1::rand += 2;
printf("%d\n", n1::rand);
}
学到这,我们来看下C++的标准库命名空间:
#include
using namespace std; //std 是封C++库的命名空间
int main()
{
cout << "hello world" << endl; // hello world
return 0;
}
如若省去了这行代码:
using namespace std;
想要输出hello world就要这样做:
#include
int main()
{
std::cout << "hello world" << std::endl;
return 0;
}
当然也可以这样:
#include
using std::cout;
int main()
{
cout << "hello world" << std::endl;
return 0;
}
这就充分运用到了命名空间,至于为什么会这样相信不需要我解释大家就能悟出来哈。