【C++】命名空间 以及 如何理解using namespace std;

news2024/10/6 2:32:08

目录

命名空间

1.由来

2.概念

3.使用

方法一

方法二

方法三

4.嵌套使用


命名空间

        很多人在学习C++的时候,第一个代码想必是如下样子的。和C语言相比,库函数换了,同时多了一个 using namespace std; 但是,你真的了解 using namespace std; 的真实作用吗?去掉 using namespace std; 会有什么影响呢?一定要加上这句话,才可以完整地打出一个Hello World 程序吗?有没有不加的办法?还是老师说要加上这句话,于是就加了。
        如果对于前面的问题,你都理解了,那么很遗憾,本部分内容不是为你准备的,如果向了解缺省参数,倒是可以看一下。如果你并不知道,并且你也想了解它们,那么恭喜你,这一部分的内容就是为你而准备的!

#include<iostream>
using namespace std;

int main()
{
	cout << "Hello World!" << endl;
	return 0;
}

1.由来

        我们知道,C++起初是Bjarne Stroustrup博士在C语言的基础上,不断加入新的特性产生的。那么C++肯定是为了弥补C语言的一些不足之处。那么命名空间是为了解决C语言的什么问题呢?

        我们看到下面左右两边的程序,右边相比于左边上面的,多了一行包含 stdlib.h 的头文件,就报错了,并且错误信息也在下方——“rand” 重定义。很容易联想到,stdlib.h 库里面是有 rand 函数的,我们可以用来生成随机数,那么就是自定义的全局变量名,和库里面的变量名冲突了。但是,我们将这个 rand 变量放到 main 函数内部,让它成为局部变量,就没有这个问题。这是因为,stdlib.h 是在全局域里面的,如果定义全局变量 rand,那么该变量也在全局域,自然会发生冲突,但是如果相同的名字,一个在全局域一个在局部域,就不会冲突。又比如两个不同的函数里面,都定义了 int a; 变量,也是可以的。

         与此同时,如果在一个项目组里面,组内成员分别负责不同板块的代码编写。如果组员A 和 组员B 都使用 Add 作为某个函数的函数名,或者是起了相同名字的变量(全局)等等,那么最后项目汇总起来,也会报错。

        所以,C语言在这方面会产生两个主要的问题,一是自己定义和库里面的名字冲突;二是项目组里面,多个人之间的名字冲突。为了解决这个问题,博士就在C++里面加上了命名空间这一概念,命名空间是唯一识别的一套名字,这样当对象来自不同的地方但是名字相同的时候就不会含糊不清了。

2.概念

        命名空间定义的实际上是一个,这个域相当于在全局域的基础之上,又加了一层域,就是命名空间域。并且,命名空间只影响其内部的变量,函数等等的使用不影响生命周期。上面讲到,同一个域里面不可以有同名变量,但是不同的域里面可以有。那么定义了命名空间,增加出来的命名空间域,就可以解决上面的问题。假设一个组里面有A、B两个人写代码,A将他的代码放到 A域 里面,B将他的代码放到 B域 里面,这也即使两个人定义了同名变量,也不影响。

        命名空间使用规则并不难,需要使用到关键字 namespace。如下代码,namespace 加上 该命名空间的名字,再加上花括号即可。花括号里面可以写任意的变量或者函数名,这些内容就成了该命名空间里面的,相当于和外界隔绝,如果不声明一下要使用,编译器是无法找到的,如何声明下文会讲。但是一个命名空间里面自然也是不可以有同名变量,除非是在不同的函数里面,如下。

namespace name
{
	int a;
	double b;
	char c;

	int Add(int m, int n)
	{
		int a = m + n;
		return a;
	}

	int Minus(int m, int n)
	{
		int a = m - n;
		return a;
	}

}

        如下,左边两个是头文件,右边的是.cpp 文件,将两个头文件包含进去,写出Hello World 的代码,也报错,原因如下,struct Node 和 m 重定义。

        但是我们把两个头文件,分别放到两个命名空间,就可以避免这个问题。

3.使用

         上面讲到,如果不声明,编译器无法找到 命名空间里面的内容。那么如何做声明呢?有三种方法。

1.指定命名空间访问。
2.全局展开,一般情况下,不建议全局展开。
3.部分。

方法一

        首先看到平时练习最常用的,全局展开。如下图,对于命名空间 AQueue ,直接使用using namespace AQueue;  就是全局展开,相当于告诉编译器:找变量名、函数等等,除了局部域和全局域,也可以去AQueue这个域找

        但是注意下图的代码,并没有全局展开头文件List.h 里面的 BList 这个命名空间,那么是不是代表BList 这个命名空间被取消了?并不是,命名空间还在那里,只不过是编译器寻找变量名等等不会去 BList 这个命名空间里面找而已。展不展开只是影响编译的时候,编译器的查找规则

         到这里我们就恍然大悟,为什么要加上 using namespace std; 是为了将标准库全局展开std这个命名空间就是标准库专门构建的一道防线,防止自己定义的内容和标准库里面的起冲突,造成名字污染。那么如果随随便便就使用 using namespace std;  不就相当于将别人辛辛苦苦建立起来的 “长城” 给摧毁了吗?导致 std 这个命名空间形同虚设。所以,在做项目开发的时候,是不可以直接全局展开标准库的。但是如果是自己日常代码练习,就无所谓。

        如下,将 using namespace std; 注释掉,使用cout 、endl 等等关键字,下面直接报错“未定义标识符”。也可以印证上面所说的,这是因为编译器不会去 std 这个命名空间寻找内容,所以找不到。

方法二

         第二种方法是指定命名空间访问。这里涉及到一个运算符 :: 没错就是两个冒号,它的名字是域作用限定符。A::B,其含义是,B这个变量,指定到命名空间A去寻找。

        给出如下代码,请问其结果是两个都输出 10 吗?第一个,根据局部优先原则,无疑是10。但是第二个输出,由于多了一个域作用限定符,会直接在该运算符左边的命名空间去寻找变量,左边命名空间是,空实际上代表全局,所以第二个输出20。

int a = 20;

void f1()
{
	int a = 10;
	printf("%d\n", a);
	printf("%d\n", ::a);
}

        如下代码,也可以顺利输出 Hello World!不需要全局展开标准库,直接使用域作用限定符去std命名空间查找。但是这里也会产生一个问题,cout 和 endl 是经常要使用到的,所以如果不全局展开,每次都指定命名空间访问,会特别麻烦,所以有了第三种方法,部分展开。

#include<iostream>

int main()
{
	std::cout << "Hello World!" << std::endl;
	return 0;
}

方法三

        部分展开就很好用,比如对于cout,部分展开之后,可以直接使用,不需要用 :: 了。如下,using 命名空间::成员  即可。

4.嵌套使用

        当然了,命名空间也是可以嵌套的,如下图,命名空间 BList 里面嵌套使用命名空间B,在右边的 main 函数里面,可以多重嵌套使用。

        关于命名空间和using namespace std; 就介绍到这里,相信看完本文对它们的理解一定有所加深!

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

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

相关文章

Allegro174版本新功能介绍之高阶Contour模式使用

Allegro174版本新功能介绍之高阶Contour模式使用 在Allegro低版本166以及172版本中,有Contour命令,但是只有沿着routekeepin和Connect Line功能,如下图 当升级到了174版本的时候,Allegro支持沿着任意目标走线,甚至是过孔和铜皮,如下图 具体操作介绍如下 以沿着这块铜皮轮…

一元三次方程求解 -- 二分查找

[NOIP2001 提高组] 一元三次方题目描述思路codetag&#xff1a;数学&#xff0c;二分查找 题目链接&#xff1a;洛谷P1024: [NOIP2001 提高组] 一元三次方 题目描述 思路 先对三次函数求导得到二次函数 3ax22bxc03ax^2 2bx c 03ax22bxc0 然后利用求根公式计算出两个极值点 …

Vue--》Vue3自定义组件以及新组件的使用讲解

目录 customRef Vue3提供的新组件 Fragment Teleport Suspense Vue3中全局API的改变 customRef 创建一个自定义的ref&#xff0c;并对其依赖项跟踪和更新触发进行显示控制。 <template><input type"text" v-model"keyword"><h3>…

谷粒学苑项目-第一章公共模块下的Swagger配置类-1.4

一、在common子模块下创建Swagger配置类 1. guli_parent->common子模块->service_base子模块->SwaggerConfig配置类 common子模块是pom类型 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId>…

【Java寒假打卡】Java基础-集合Collection

【Java寒假打卡】Java基础-集合Collection集合与数组之间的区别集合体系结构Collection常用的方法集合-迭代器迭代器原理分析迭代器删除方法的注意事项增强for循环集合与数组之间的区别 数组的长度是不可变的&#xff0c;集合的长度是可变的数组可以存基本数据类型和引用数据类…

Xilinx AXI4 协议

AXI4 相对复杂&#xff0c;但 SOC 开发者必须掌握。AXI 协议的具体内容可参考 Xilinx UG761 AXI Reference Guide。在这里我们简单了解一下。 AXI4 所采用的是一种 READY&#xff0c;VALID 握手通信机制&#xff0c;即主从模块进行数据通信前&#xff0c;先根据操作对各所用到的…

填满背包方案数OJ

目录 LintCode 炼码物品大小不重复的填满背包的方案数 LintCode 炼码 物品大小存在重复情况 LintCode 炼码不重复的组合个数 完全背包_牛客题霸_牛客网 LintCode 炼码物品大小不重复的填满背包的方案数 描述给出 n 个物品, 以及一个数组, nums[i]代表第i个物品的大小, 保证大…

编辑PDF文件的两种方法

PDF文件具备较好的稳定性、兼容性&#xff0c;在日常工作中的应用非常广泛&#xff0c;但想要编辑文件内容就不那么容易了&#xff0c;下面来说说编辑PDF文件的两种方法。 方法一&#xff1a; 我们知道&#xff0c;查看PDF文件只需要阅读器就可以了&#xff0c;如果想对文件内…

springboot 整合 webservice服务

目录webservice百科创建一个springboot项目并导入相关依赖编写webservice接口编写实现类发布webservice浏览器访问postman调用在前一段时间用到了webservice服务&#xff0c;今天整理了一下&#xff0c;记录下来。webservice百科 Web Service是一个平台独立的&#xff0c;低耦…

Apifox调用Security权限接口

Apifox调用Security权限接口1. SpringBoot3.0集成SpringSecurity1.1 pom1.2 properties配置2. Apifox 配置2.1 配置根目录Auth2.2 ApiFox 分享调用本地接口本教程环境&#xff1a; Apifox&#xff1a;2.2.14 &#xff08;建议更新到最新版本&#xff0c;老版本Auth从父级继承可…

flowable数据表详解

爬虫组件分析目录概述需求&#xff1a;设计思路实现思路分析1.flowable2.数据表的命名规则3.ACT_RU_*4.ACT_ID_*5.ACT_HI_*数据表的介绍参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hard…

AjaxRedis问题总结

一、JQuery——Ajax实现三大方法的应用及区别&#xff08;get,post,ajax&#xff09; 1. $.get()方法 <script type"text/javascript">$(function () {$("#send").click(function () {$.get("AjaxHandler.ashx", {username: $("#use…

【操作系统】国科大《高级操作系统》思考题整理

参考用书&#xff1a;《Linux内核设计的艺术》 引言 国科大杨力祥《高级操作系统》思考题整理 思考题 为什么开始启动计算机的时候&#xff0c;执行的是BIOS代码而不是操作系统自身的代码&#xff1f;&#xff08;P1&#xff0c;3&#xff09; 加电的一瞬间&#xff0c;计算…

graphviz安装及使用、决策树生成

一、graphviz下载安装 下载网址&#xff1a;http://www.graphviz.org/download/ 选择合适版本下载 1.1 双击安装 1.2 点击下一步 1.3 点击我接受 1.4 添加至系统路径 勾选添加至当前用户的系统路径&#xff0c;创建桌面图标可选&#xff0c;点击下一步 1.5 选择安装位置 浏…

「设备树」dtb给内核的两种工作模式

一&#xff0c;传递dtb给内核对于传统bootloader提供两种工作模式&#xff1a;一是启动加载模式&#xff08;start loading&#xff09;&#xff0c;一是下载模式&#xff08;downloading&#xff09;工作在启动加载模式时&#xff0c;bootloader会自动执行bootcmd命令&#xf…

AGV移动机器人PID运动控制

PID算法基本原理 PID算法是控制行业最经典、最简单、而又最能体现反馈控制思想的算法&#xff0c;PID算法利用反馈来检测偏差信号&#xff0c;并通过偏差信号来控制被控量。而控制器本身就是比例、积分、微分三个环节的加和。其功能框如图1所示&#xff1a; 考虑在某个特定的时…

C语言-指针进阶(9.1)

目录 思维导图&#xff1a; 1. 字符指针 2. 指针数组 3. 数组指针 3.1 数组指针的定义 3.2 &数组名VS数组名 3.3 数组指针的使用 4. 数组传参和指针传参 4.1 一维数组传参 4.2 二维数组传参 4.3 一级指针传参 4.4 二级指针传参 写在最后 思维导图&#xff1a;…

年底赶进度,如何将开发风险降到最低?

1、科学规划风险策略和控制流程 针对开发流程各环节中可能存在的风险&#xff0c;项目经理需要进行项目风险分析&#xff0c;并制定符合项目特点的风险评估和监督机制&#xff0c;实行岗位负责制&#xff0c;提前制定好控制策略&#xff0c;将开发风险降到最低。 如何将开发风险…

分布式基础篇2——分布式组件

一、SpringCloud Alibaba1、简介2、为什么使用3、版本选择4、依赖选择二、SpringCloud Alibaba 组件1、Nacos作为注册中心2、OpenFeign3、Nacos作为配置中心namespaceData IDGroup同时加载多个配置文件三、Spring Cloud1、GateWay简介三大核心部分网关的使用视频来源: 【Java项…

Ansible剧本流程控制

handlers触发器 notify&#xff1a;监控上面的模块执行是否发生变化 chufa&#xff1a;自定义的任务名称&#xff0c;自动去handlers里面匹配相对应的任务名称执行动作 下方是copy了/data/copy/下的文件到server2组里的主机/data/monster/handlers/下&#xff0c;notify监控发…