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("%dn", 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("%pn", rand);//函数指针
	printf("%dn", 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("%dn", 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("%dn", WD::a);//2.指定命名空间
	//using WD::a;//3.仅展开a
}

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

  注意

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

   2️⃣ using namespace std;:允许用

  所以两者缺一不可

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>