C++命名空间

Posted 跳动的bit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++命名空间相关的知识,希望对你有一定的参考价值。

一、写在前面

对比 C 语言,一般 C++ 每增加一个语法都是为了解决一些 C 语言做不到的事或者是 C 语言做的不好的地方

在 C/C++ 中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace 关键字的出现就是针对这种问题的。

❗ C语言命名冲突示例 ❕

在不同的作用域中,可以定义同名的变量;在同一作用域下,不能定义同名的变量

#include<stdio.h>
//#include<stdlib.h>
int a = 0;
int rand = 10;
int main()

	int a = 1;
	printf("%d\\n", rand);
	return 0;

📝 分析:

可以看到我们定义了一个 rand 变量输出是没有问题的,但如果包含了 stdlib 头时就会产生命名冲突,此时我们的 rand 变量就和库里的产生冲突;
实际除此之外在大型项目开发时,还有可能和同事之间发生冲突。C 语言面对这种问题是无法解决的,而对于这种场景 C++ 使用了命名空间

二、命名空间定义

定义命名空间,需要使用到 namespace 关键字,后面跟命名空间的名字,然后接一对 即可, 中即为命名空间的成员

⚠ 注意一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

//1. 普通的命名空间
namespace N1 // N1为命名空间的名称

 	//命名空间中的内容,既可以定义变量,也可以定义函数
 	int a;
 	int Add(int left, int right)
 	
 		return left + right;
 	

//2. 命名空间可以嵌套
namespace N2

	 int a;
	 int b;
	 int Add(int left, int right)
	 
		 return left + right;
	 
 
 	namespace N3
 	
		 int c;
		 int d;
 		int Sub(int left, int right)
 		
			 return left - right;
		
	

//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
namespace N1

 	int a = 10;

namespace N1

 	int b = 20;

❗ 用命名空间解决变量 rand 和 stdlib 库里的命名冲突 ❕

#include<stdio.h>
#include<stdlib.h>
namespace WD//定义了一个命名空间域

	int rand = 10;//定义变量
	int Add(int x, int y)//定义函数
	
		return x + y;	
	
	struct Node//定义结构体类型
	
		struct Node* next;
		int val;	
	;

int main()

	printf("%p\\n", rand);//函数指针
	printf("%d\\n", WD::rand);//rand变量;‘::’叫做域作用限定符
	WD::Add(3, 5);//调用函数
	struct WD::Node node1;//结构体
	
	return 0;

❗ 嵌套命名空间 ❕

#include<stdio.h>
#include<stdlib.h>
namespace WD

	int w = 20;
	int h = 10;
	namespace WH//嵌套命名空间域
	
		int w = 10;
		int h = 20;
	

int main()

	printf("%d\\n", WD::WH::h);//访问嵌套命名空间
	return 0;

❗ 相同名称的命名空间 ❕

namespace WD

	int a = 10;
	int b = 20;
	namespace WH
	
		int a = 20;
		int b = 10;
	

namespace WD//相同名称的命名空间

	int rand = 50;
	//int a = 10;//err,在合并的时候冲突了

三、命名空间使用

❓ 如何使用命名空间里的东西 ❔

1️⃣ 全部直接展开到全局

using namespace WD;
//using namespace std;//std是包含C++标准库的命名空间

  💨优点:用起来方便

  💨缺点:自己定义的东西也会暴露,导致命名污染

2️⃣ 访问每个命名空间中的东西时,指定命名空间

std::rand;

  💨优点:不存在命名污染

  💨缺点:如果要去访问多个命名空间里的东西时,需要一一指定

3️⃣ 仅展开常用的内容

using WD::Node;
using WD::Add;

  💨优点:不会造成大面积的污染;把常用的展开后,也不需要一一指定


namespace WD

	int a = 10;
	int b = 20;
	//...

int main()

	//using namespace WD;//1.展开WD空间所有内容
	//printf("%d\\n", WD::a);//2.指定命名空间
	//using WD::a;//3.仅展开a

❓ 上面说了 C++ 把库里的东西都放到 std 这个域里了,那直接展开 std 不就行了或者包头 ❔

  注意

   1️⃣ #include <iostream>:展开定义

   2️⃣ using namespace std;:允许用

  所以两者缺一不可

以上是关于C++命名空间的主要内容,如果未能解决你的问题,请参考以下文章

C++ 项目相关知识命名空间

C++ 命名空间 (namespace)

在 C++ 中,啥是“命名空间别名”?

C++ 中未命名命名空间的使用

C++ 中的头文件和命名空间

命名空间的使用方式(c++基础语法一)