【细品C++】命名空间详解(namespace)

2023-06-23 14:35:45 浏览数 (1)

写在前面

本篇文章是C 中的命名空间详解,也是笔者第一篇关于C 的文章,同时,由于本篇文章旨在面向有一定C基础的C 初学者,所以会使用部分C语法。希望对你命名空间的学习有所帮助。

为什么有命名空间

如果你对C语言有过一定了解的话,你应该会知道在C语言中为变量,函数取名字的时候,如果和库里的某个关键字或者标识符的名称重名就会发生命名冲突的错误。而C 是在C语言的基础上设计改进的,不仅相较于C语言有更多的关键字和标识符,也继承了这种缺陷(某种角度来说)。但是既然是升级版,C 也为此提供了解决方案,这就是本篇文章所讲的命名空间namespace

由于C 大量存在的标识符(变量、函数和类的名称),并且这些标识符处于全局作用域中,为避免命名冲突或命名污染namespace对这些标识符的名称进行了本地化,使编译器在全局作用域中不直接检索到这些标识符。

代码语言:javascript复制
#include<stdio.h>
#include<stdlib.h>

//C语言无法处理这样的命名冲突
int rand = 0;

int main()
{
	printf("%dn", rand);
	return 0;
}
//编译错误
// error C2365: “rand”: 重定义;以前的定义是“函数”
//  message : 参见“rand”的声明
//
// 
//不仅仅是与库里的命名可能发生冲突
// 实际工作中,在大的项目中,会使用很多变量、函数,命名很难做到不重复
// C  为解决这一痛点,设计出了namespace
//

命名空间定义

使用namespace定义命名空间,空间的名字有自己定。下面用代码演示如何定义:

代码语言:javascript复制
#include<stdio.h>
#include<stdlib.h>

//
// 命名空间的名字通常是开发者项目名称
// 
// 1.正常的命名空间定义
//
namespace demo
{
	//命名空间可以定义变量/函数/结构体

	int rand = 0;//在这里定义的变量rand是不会与库函数rand起冲突的

	int Add(int a, int b)
	{
		return a   b;
	}

	struct S
	{
		int a;
		char b;
	};
}

//2.命名空间嵌套定义
namespace demo1
{
	int a = 0;

	namespace demo2
	{
		int b = 0;
	}
}

//同名命名空间合并
namespace demo
{
	//不止是同一个文件中,只要是在同一个工程文件中,同名的命名空间会被合并

	//这里定义了同一命名空间已定义的变量名便会报错
	//int rand = 1;
	// error C2374: “demo::rand”: 重定义;多次初始化
	//参见“demo::rand”的声明
	//
	struct S s1 = { 1,'A' };
}

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

命名空间使用

使用演示:

代码语言:javascript复制
namespace show
{
	int a = 0;
	int b = 10;

	struct S
	{
		int size;
		char* str;
	};

	int sub(int a, int b)
	{
		return a - b;
	}
	namespace min
	{
		char ch = 'A';
	}
}

int main()
{
	//无法之间使用
	//printf("%dn", a);//报错:“a”: 未声明的标识符

	return 0;
}

用以下三种方式:

加命名空间名称及作用域限定符

代码语言:javascript复制
int main()
{
	struct show::S p = { 0,NULL };

	printf("%dn", show::a);
	printf("%cn", show::min::ch);

	int s = show::sub(show::b, show::a);

	return 0;
}

使用using将命名空间内某个成员引入

代码语言:javascript复制
using show::a;

int main()
{
	printf("%dn", a);
	printf("%dn", show::b);

	return 0;
}

使用using namespace命名空间名称引入

代码语言:javascript复制
using namespace show;

int main()
{
	a = sub(b, a);
	printf("%d %d", a, b);

	return 0;
}

结语

非常感谢各位读者能读完这篇文章,如果你觉得做的还不错的话,可以点赞收藏分享,让更多的朋友知道,当然,如果你觉得有什么问题的话也欢迎在评论区留言或私信告诉我哦!下期再会!

彩蛋

源码传送门:GitHub 命名空间 gitee 命名空间

0 人点赞