详解C++中的命名空间(namespace)

news2024/9/30 17:32:29

个人主页:平行线也会相交
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C++之路】
在这里插入图片描述

目录

  • C++关键字(C++98)
  • 命名冲突
  • 命名空间
    • 命名空间的定义
    • 局部域和全局域的关系
    • 命名空间域
    • 小结
    • 命名空间中可以定义哪些内容
  • 嵌套命名空间
  • 总结

C++关键字(C++98)

在C++中,总共有63个关键字,大家还记得在C语言中有多少个关键字吗,没错,在C语言中总共有32个关键字。
下面是C++的关键字:

asmdoifauto
returntrycontinuedouble
inlineshorttypedeffor
booldynamic_castintsigned
typeidpublicbreakelse
longsizeoftypenamethrow
caseenummutablestatic
unionwchar_tcatchexplicit
namespacestatic_castunsigneddefault
charexportnewstruct
usingfriendclassextern
operatorswitchvirtualregister
constfalseprivatetemplate
voidtrueconst_castfloat
protectedthisvolatilewhile
deletegotoreinterpret_cast

命名冲突

在这里插入图片描述
可以看到:上述代码我们可以通过。
那现在这段代码呢?请看:
在这里插入图片描述

我们发现rand出现了重定义的错误那为什么rand发生了冲突了呢?其实rand这里是跟发生了冲突。std中有一个函数也叫rand,所以就会发生命名冲突的问题。
发生命名冲突的原因有两种:

1.跟库里发生冲突。
2.互相之间发生冲突。

其实命名冲突这个问题挺麻烦的,我们并不知道库中是否有这个变量,在这个基础上,如果我们又重新定义了这个变量,此时就会出现命名冲突的问题。为了解决命名冲突的问题,就引出了命名空间

命名空间

嗯,namespace就是命名空间的意思,也是C++中的一个关键字,就是用来解决命名冲突的问题的。
这里,我们先来引出一个问题,请看下面代码:

#include<iostream>
using namespace std;
int main()
{

	return 0;
}

在C++中,为什么我们一般要加上using namespace std;呢?

命名空间的定义

命名空间,即namespace,后面跟着命名空间的名字,然后接一对{}{}中的内容就是命名空间的成员
命名空间namespace可以定义一个出来。
举个例子:
在这里插入图片描述
我们可以看到上图的代码出现了rand重定义的问题,我们如果不想出现这个问题,就可以用namespace定义一个域出来以解决重定义这个问题。
请看解决方法:

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

//域
namespace hello
{
	//hello这个域就会把域中的内容(rand)进行一个隔离
	//这里要注意,域中的rand与主函数中的rand不是一回事。
	int rand = 0;
}

int main()
{
	printf("%d\n", rand);
	return 0;
}

在这里插入图片描述
这个运行结果也说明了域中的rand与主函数中的rand不是一回事。

局部域和全局域的关系

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

int a = 0;

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

上面这个代码中的两个a就可以同时存在
我们把主函数外面的a看作是全局域中的a,把主函数里面中的a看作是局部域中的a同时,我们还要知道一个点局部域和全局域既影响访问,也影响生命周期。域分为好几种,作用域只是域中的一种。
域总共分为下面四种:

类域
命名空间域
局部域
全局域

我们来运行上面的代码:

在这里插入图片描述
因为局部域中的a优先,所以这里打印出来的是局部域中变量a的值,即打印出来的是1,如果我们想打印全局域中的a中的值怎么办呢?我们可以这样:

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

int a = 0;

int main()
{
	int a = 1;
	printf("%d\n", a); 

	//  ::称为域作用限定符
	printf("%d\n",::a);
	return 0;
}

在这里插入图片描述
运行结果如上图,我们看到我们打印出来的0就是全局域中的a的值。
关于局部域和全局域的关系是这样的:

我们是默认从局部域开始搜索的,即局部优先;当然,如果局部没有的话,我们就会去全局域进行搜索,所以有局部先访问局部,没有局部才会去访问全局。

我们通过域作用限定符::可以去直接访问全局域。即上面的代码,注意观察,::的前面是不加任何东西的(注意前面不需要我们加空格),意思就是我们直接去访问全局域。

命名空间域

在这里插入图片描述
上图代码中总共有三个域(局部域、全局域、命名空间域),每个域中都有一个变量a,我们如何去访问这三个作用域中的a呢,请看下面:
在这里插入图片描述
我们现在把全局域中的变量a注释掉看看运行结果,所以来看下面这段代码的运行结果:
在这里插入图片描述
我们发现程序根本运行不了,所以这里就报错了。
所以我们通过这个程序发现,这个程序并不会去到命名空间里去进行搜索;那这里就会引出一个新的问题,程序什么时候才会去到命名空间域中去进行搜索呢?
这里有两种可能性会去搜索命名空间域中的内容

1.我们展开了命名空间域
2.指定访问命名空间

我们先来看第一种(展开命名空间)
在这里插入图片描述
如果我们不展开的话:

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

int a = 2;

namespace hello
{
	int a = 1;
}

//展开命名空间
//using namespace hello;

int main()
{
	int a = 0;
	printf("%d\n", a);
	return 0;
}

上面就是我们不对命名空间进行展开,上面代码中的3个变量a依然可以同时存在

补充一点,我们C++中常用的using namespace std;展开的是std标准库中的命名空间
现在如果我们想访问命名空间中的变量a,我们可以采用第二种方式(指定访问命名空间)

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

int a = 2;

namespace hello
{
	int a = 1;
}

//展开命名空间
//using namespace hello;

int main()
{
	int a = 0;
	printf("%d\n", a);
	printf("%d\n", ::a);
	printf("%d\n", hello::a);
	return 0;
}

在这里插入图片描述
上面的代码中我们虽然没有对命名空间进行展开,但是我们指定了命名空间。
现在新的问题来了,如果我们把命名空间展开会发生什么呢?请看:

在这里插入图片描述
上述代码中,我们把命名空间里的内容进行展开,展开的意思就是编译时把命名空间里的内容暴露到全局,是是否会到命名空间里面去搜索,,而此时全局域中已经有一个变量a了,所以会出现上图a不明确的问题。
所以我们现在再来看namespace这个关键字发现它并不友好,它会把我们的命名空间进行展开,而我们为什么要把命名空间进行展开呢?命名空间进行展开的意义何在?

命名空间就是为了防止自己的内容与其它域发生冲突而设立的。

小结

我们虽然可以指定指定命名空间里面的内容,但是这样不是很方便,所以有些地方有些时候我们会把命名空间进行展开,一旦我们把命名空间进行展开,就可能会出现一系列问题。比如,重定义问题、某个变量不明确等等问题。所以,我们以后不要轻易使用using namespace
现在,我们再来看开头还没有解决的问题:
在这里插入图片描述
我们既然无法把rand定义在全局域中,那就直接把rand定义在一个命名空间域并不对这个域进行展开就好了,请看:
在这里插入图片描述
在这里插入图片描述
所以我们利用命名空间就可以解决开头rand重定义的问题,但是这个问题C语言无法解决,而C++中的命名空间就可以解决。

命名空间中可以定义哪些内容

在命名空间中,我们可以定义很多东西,比如结构体类型、定义变量、定义函数等都是可以的。请看举例:

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

namespace hello
{
	int rand = 10;
	
	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int data;
	};
}

int main()
{
	return 0;
}

嵌套命名空间

命名空间是可以进行嵌套的,比如:

//嵌套命名空间
#include<stdio.h>
#include<stdlib.h>

namespace N1
{
	int a = 0;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}

	namespace N2
	{
		int a = 1;
		int c = 0;
		int d = 0;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}

补充一点:C++中的C++库里的所有东西都会被分装在std命名空间中stl是C++标准库的一部分cout等都在C++标准库中

我们如何访问嵌套命名空间呢?请看举例:
在这里插入图片描述

我们知道不同的域可以有同名名变量,但是同一个域不能有同名变量。我们同一个命名空间如若给非要给同样的变量,这个时候嵌套命名空间就派上用场了。
我们在平常最常见的C++代码大体是长这样的,请看:

#include<iostream>
using namespace std;

int main()
{
	return 0;
}

其实这样直接展开的话会有风险,我们定义的如果跟库中的重名,就报错了。所以项目里面尽量不要去进行展开。注意,展开不一定会报错。如果是日常练习的话(代码少),就可以直接展开;那如果是项目中的话,前往不要随意对命名空间进行展开。建议直接访问指定命名空间,比如:
在这里插入图片描述
但是如果我们一个项目中有非常多cout的话,我们不可能要输入非常多次的std::,所以这里推荐一种非常实用的方式,请看:
在这里插入图片描述
这样的话,我们就不需要把整个命名空间进行展开了,我们直接把最常用的展开就可以了。

总结

命名空间的存在是为了解决C语言的一个缺陷,这个缺陷叫做命名冲突。为了解决命名冲突问题,于是C++就引入了命名空间的内容。我们对命名空间进行搜索主要有三种方式:第一:展开命名空间;第二:直接访问命名空间;第三:访问某个。(其中第二种第三种都是通过域作用限定符来进行操作的)。
同时,我们在对命名空间进行展开的时候需要格外小心,不要轻易的对命名空间进行展开。
好了,以上就是C++中命名空间的内容,算是C++中的开头。
就到这里吧,下次见喽各位,再见啦!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/429110.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

音视频开发常用分析工具介绍

综述 工欲善其事&#xff0c;必先利其器&#xff1b;兵马未到&#xff0c;粮草先行。 在音视频开发过程中&#xff0c;利用工具可以更方便、更直观、更快捷的分析音视频的数据&#xff0c;便于开发过程中分析、调试和解决问题。 现总结一些音视频开发过程中常用的分析工具。…

Android library native 代码不能调试解决方法汇总

android native开发会碰到native代码无法调试问题&#xff0c;而app主工程中的native代码是可以调试的。如果项目中存在多个module&#xff0c;那么在application模块中依赖library模块&#xff0c;并且library模块中有native代码的时候&#xff0c;当debug library模块中的这些…

如何高效获取数据价值?

导读&#xff1a;上一篇《大数据架构知识点详解&#xff1a;国产数据库创新、湖仓一体实践…》中我们阐述了四大体系之数据架构体系&#xff0c;解释了云原生大数据实践、国产数据库创新变革、湖仓一体落地实践、OLAP 发展趋势四个论坛的架构思路。 接下来是四大体系之二数据效…

【Linux】2、Linux 的基本命令

目录一、Linux 的目录结构二、Linux 命令三、ls 命令四、cd五、pwd六、特殊路径符七、mkdir八、touch九、cat 命令十、more十一、cp十二、mv十三、rm十四、which十五、find十六、grep十七、wc十八、管道符十九、echo二十、重定向符二十一、tail 命令一、Linux 的目录结构 &…

直播观看指南|SOFA 五周年,Live Long and Prosper!

SOFA 五周年活动将于 2023 年 4 月 15 日&#xff08;周六&#xff09;12:00 在北京朝阳区恒通国际创新园 C6 栋 C work 举行&#xff01;期待社区的小伙伴和对开源感兴趣的小伙伴们一起来现场玩哦&#xff5e;当然啦&#xff0c;不能来现场的小伙伴们也别担心&#xff0c;我们…

第二十一章 案例TodoList之新增数据

前一小节&#xff0c;我们已经完成了数据的动态展示&#xff0c;现在我们要完成数据的动态添加。如何添加呢&#xff1f;肯定是要通过Header组件来添加&#xff0c;但是Header组件如何将收集的任务数据&#xff0c;交给App组件并更新状态数据呢&#xff1f; 在Header组件中收集…

实现vue的条件渲染

我的需求是根据设备不同的状态 渲染不同的标签。设备状态用device_State表示。 在线上面是一个vue的标签&#xff0c;我有一个数据state &#xff0c;如何让这个标签根据数据的取值 &#xff0c;修改内容&#xff0c;如state1时&#xff0c;标签修改为离线 要根据数据的取值动态…

Python曲线拟合详解

文章目录入门参数多元拟合入门 scipy.optimize中&#xff0c;curve_fit函数可调用非线性最小二乘法进行函数拟合&#xff0c;例如&#xff0c;现在有一个高斯函数想要被拟合 yaexp⁡−(x−bc)2y a\exp-(\frac{x-b}{c})^2 yaexp−(cx−b​)2 则调用方法如下 import numpy as…

STM32基础代码学习G070CB串口透传调试(出厂默认)代码

先下载 一定记得回车换行勾选 可以参考“Quectel_BC260Y-CN_AT命令手册_V1.0.pdf” ATCGMI 查询制造商信息 ATCGMM 查询模块型号 ATCSQ 上报信号质量 ATCGATT? PS 域附着或去附着查看板子是否正常 再激活 ATQIACT1&#xff0c;最后查询ATQIACT? 配置阿里云mqtt atqmtc…

【从零开始学Skynet】实战篇《球球大作战》(十三):场景代码设计(下)

1、主循环 《球球大作战》是一款服务端运算的游戏&#xff0c;一般会使用主循环程序结构&#xff0c;让服务端处理战斗逻辑。如下图所示&#xff0c;图中的balls和foods代表服务端的状态&#xff0c;在循环中执行“食物生成”“位置更新”和“碰撞检 测”等功能&#xff0c;从而…

学习笔记 —— C++并行库OpenMP

ContentsInstallationImplement1、一个最简单的OpenMP代码&#xff1a;2、如何规定线程数2、如何设置OpenMP分配线程的schedule3、 冲突避免机制 --Reduction&#xff08;规约&#xff09;Discovery写在最前面&#xff1a; 并行化虽好&#xff0c;但并不是所有任务在并行化后都…

【MySQL学习】MySQL表的操作

目录一、表的创建1.1 创建表的语法1.2 案例二、查看表结构三、查看建表语句四、修改表4.1 修改表的语法4.2 修改案例五、删除表一、表的创建 1.1 创建表的语法 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set…

透视Android系统AMS、PMS和WMS,了解开发中的重要角色

原理 在Android系统中&#xff0c;AMS&#xff08;Activity Manager Service&#xff09;、PMS&#xff08;PackageManager Service&#xff09;和WMS&#xff08;Window Manager Service&#xff09;是三个重要的系统服务&#xff0c;它们负责管理应用程序的生命周期、处理应…

Backblaze + Cloudflare + Picgo 打造免费顺畅的图床体验

本文xlog地址&#xff1a;https://x.cosine.ren/backblaze-cloudflare-picgo-imgbed hexo 地址&#xff1a;https://ysx.cosine.ren/backblaze-cloudflare-picgo-imgbed 同步发布 最近有用到oss存储的需求&#xff0c;跟群友调研了下国内 & 国外的 oss 后&#xff0c;深感找…

大爽pygame入门教程 第一节 基础知识

作者自我介绍&#xff1a;大爽歌, b站小UP主 &#xff0c;编程1对1辅导老师 本节掌握要点&#xff1a; 文本, 图形, 键鼠事件&#xff0c;动态展示。 一、实现基础窗口 0 - 新建文件 新建001.py文件&#xff0c;内容如下 import pygamepygame.init() # pygame 初始化&#x…

什么是远程桌面连接?如何操作远程桌面?

随着时代越来越信息化、智能化、自动化&#xff0c;越来越多的企业和个人开始使用远程办公软件进行办公。其中远程桌面连接是一种非常流行的办公方式。那么&#xff0c;什么是远程桌面连接?如何操作远程桌面? 一、什么是远程桌面连接? 远程桌面连接是一种远程访问计算机的…

nginx缓冲区关闭导致下载失败问题-方案篇

问题描述 导出操作。小于200k的excel正常下载&#xff0c;大于200K的下载失败&#xff0c;异常信息如下: Cannot forward to error page for request [/xx/xx] as the response has already been committed. As a result,the response may have the wrong status code. If you…

程序员工作久了,都不会好好说人话了...互联网人的....黑话

原来工作也是会被腌入味的 前段时间有位博主吐槽 工作太久都不会说人话了 这张口的互联网味儿 瞬间梦回自己的工位 而评论区的网友们表示 这不就是”世另我“吗 一场关于互联网黑话的"掰头" 就此开始了... 维护厨房 &#xff08;厨房秒变公司&#xff09; 新…

Bagging算法预测银行客户流失率

Bagging算法预测银行客户流失率 描述 为了防止银行的客户流失&#xff0c;通过数据分析&#xff0c;识别并可视化哪些因素导致了客户流失&#xff0c;并通过建立一个预测模型&#xff0c;识别客户是否会流失&#xff0c;流失的概率有多大。以便银行的客户服务部门更加有针对性…

【CSS】使用 CSS 实现三角形 ( 宽高设置为 0 | 设置四个边框宽度 / 样式 / 颜色值 | 兼容低版本浏览器 | 基本示例 | 对话框示例 )

文章目录一、使用 CSS 实现三角形二、使用 CSS 实现三角形代码示例三、使用 CSS 实现 对话框 代码示例一、使用 CSS 实现三角形 使用 CSS 实现三角形步骤 : 首先 , 宽度 / 高度 设置为 0 ; /* 宽高设置为 0 像素 */width: 0;height: 0;然后 , 设置 4 个边框 , 每个边框都要设置…