C++ 命名空间-----namespace(超详细解析,小白必看系列)

我们都清楚在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;

}

这就充分运用到了命名空间,至于为什么会这样相信不需要我解释大家就能悟出来哈。