C++从入门到精通——命名空间

命名空间

  • 前言
  • 一、命名空间
    • 引例
    • 什么是命名空间
  • 二、命名空间定义
    • 正常的命名空间定义
    • 嵌套的命名空间
    • 多个相同名称的命名空间
  • 三、命名空间使用
    • 加命名空间名称及作用域限定符
    • 使用`using`将命名空间中某个成员引入
    • 使用`using namespace` 命名空间名称引用
    • 引用命名空间和引用头文件有什么区别


前言

命名空间是一种用于封装和组织代码的结构,可以避免名称冲突并提供更好的代码组织性。在编程中,命名空间通常用于将相关的类、函数、变量等组织在一起,形成一个独立的逻辑单元。通过使用命名空间,可以更加清晰地组织代码,提高代码的可读性和可维护性。同时,命名空间也可以用于控制访问权限,保护代码的安全性和稳定性。因此,在编程中,合理地使用命名空间是一种重要的编程实践。


一、命名空间

引例

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
 	printf("%d\n", rand);
 	return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

在这里插入图片描述
为什么会出现这种情况呢?是因为在C语言中的stdlib.h中的rand函数和我们定义的变量冲突了,这种情况在C语言中我们只能通过改变参数的名字来解决这种情况,但是在C++完全不用担心这种情况,因为C++中有着命名空间namespace来严格管控函数

什么是命名空间

命名空间顾名思义就是通过定义一个空间来封装变量,函数,是一种用来给变量和函数等标识符起一个独特且有组织的名称的机制。通过使用命名空间,可以避免在不同的代码模块中出现重名的标识符,从而提高代码的可读性和可维护性。

namespace bit
{
		……
}

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

命名空间是一个用于封装类、函数、变量等代码元素的容器,它提供了一种将相关代码组织在一起的方式,并避免了不同代码之间的命名冲突。在编程中,命名空间的存在使得代码更加清晰、有序,提高了代码的可读性和可维护性。

在C++语言中,命名空间的使用尤为普遍。通过使用命名空间,我们可以将不同模块的代码分隔开来,避免了函数和变量名称的冲突。例如,在C++标准库中,所有的标准函数和类都被定义在一个名为std的命名空间中,这样我们在使用标准库时就需要通过std::前缀来访问其中的元素。

除了C++,其他编程语言也提供了类似命名空间的机制。例如,在Python中,我们可以通过模块来实现类似命名空间的功能。每个模块都是一个独立的命名空间,其中包含了该模块中定义的所有函数、类和变量。当我们在其他模块中导入某个模块时,就可以通过该模块的名称来访问其中的元素,从而避免了命名冲突。

命名空间的使用不仅可以提高代码的可读性和可维护性,还可以帮助我们更好地组织和管理代码。通过将相关的代码元素放在同一个命名空间中,我们可以更加清晰地表达代码之间的逻辑关系,使得代码更加易于理解和维护。

在实际开发中,我们应该充分利用命名空间的特性,合理地组织和管理代码。同时,我们也需要注意避免过度使用命名空间,以免造成代码结构的混乱和复杂性的增加。只有在适当的时候使用命名空间,才能更好地发挥其优势,提高代码的质量和效率。

二、命名空间定义

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

ps:下文中的bit是我自己定义的,不是只能这样定义,也可以换成其他名称,名称根据自己的喜好定义即可,如果是在项目中,可以按照项目名称来定义

正常的命名空间定义

namespace bit
{
	// 命名空间中可以定义变量/函数/类型
	int rand = 10;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
}

嵌套的命名空间

//命名空间可以嵌套
namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N2
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}

多个相同名称的命名空间

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

namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N2
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}
namespace N1
{
	int Mul(int left, int right)
	{
		return left * right;
	}
}

上面相同的命名空间将在代码的运行过程中变成下述情况(当然实际的在编译运行的时候肯定不是这样的,但实际意义是一样的,读者可以按照下述来理解)

namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N2
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
	int Mul(int left, int right)
	{
	return left * right;
	}
}

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

三、命名空间使用

命名空间中成员该如何使用呢?

比如:

namespace bit
{
	// 命名空间中可以定义变量/函数/类型
	int a = 0;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
}
int main()
{
	// 编译报错:error C2065: “a”: 未声明的标识符
	printf("%d\n", a);
	return 0;
}

在这里插入图片描述
为什么会出现报错呢?是因为a已经被放到我们定义的namespace bit中了,编译器直接查找的话是查找不到的

在这里我涉及一些编译器查找的知识,我们在同时定义一个变量的全局变量和局部变量

int a = 0;
int main()
{
	int a = 1;
	// 编译报错:error C2065: “a”: 未声明的标识符
	printf("%d\n", a);
	return 0;
}

在这里插入图片描述
我们可以明显看到编译器打印了局部变量,之所以打印局部变量是因为编译器查找是按照

  • 局部变量
  • 全局变量

这两种情况来查找的,正常情况下是没有namespace的访问权利的,我们需要通过代码来获得访问权利,即使编译器查找变成

  • 局部变量
  • 全局变量
  • namespace

命名空间的使用有三种方式:

ps:命名空间里的未赋值的变量是随机值吗?
在许多编程语言中,命名空间中未赋值的变量通常被初始化为默认值,而不是随机值。这些默认值可能是零、空、false或null,具体取决于编程语言和变量的类型。对于数字类型的变量,通常将其初始化为零或null。对于布尔类型的变量,通常将其初始化为false。对于字符串类型的变量,通常将其初始化为空字符串。对于对象类型的变量,通常将其初始化为null。这样可以确保在使用变量之前,它们都有一个已定义的值,从而避免出现随机的不确定性。

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

ps:我们可以printf("%d\n", ::a);这样a是全局变量

int main()
{
    printf("%d\n", N::a);
    //打印嵌套命名空间printf("%d\n", N::N1::a);
    return 0;    
}

这样打印的是名称为N命名空间里的a变量

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

直接使用using可以便于不需要每次都打印N::b

using N::b;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;    
}

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

直接引用NN会成为上述所说的第三查找标准

using namespce N;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

引用命名空间和引用头文件有什么区别

在C++编程中,引用命名空间和引用头文件是两个常见的概念,它们各自承担着不同的角色,并在编程过程中发挥着不可或缺的作用。虽然它们都与代码的组织和重用有关,但它们的用途和效果却有所不同。

首先,引用命名空间(using namespace)主要是为了解决命名冲突和简化代码书写。在大型项目中,不同的库和模块可能会使用相同的名称来命名不同的函数或类。为了避免这种命名冲突,C++引入了命名空间的概念。通过引用命名空间,我们可以告诉编译器我们希望使用哪个命名空间中的名称,从而避免因为名称冲突而导致的编译错误。例如,当我们在代码中写using namespace std;时,我们就告诉编译器我们想使用标准库中的所有名称,而不需要在每次调用标准库函数或类时都加上std::前缀。

而引用头文件(#include)则是C++中实现代码重用和模块化编程的重要手段。头文件通常包含了类的声明、函数的原型、常量定义等,它们可以被多个源文件共享和引用。通过引用头文件,我们可以实现代码的模块化,使得每个模块只关心自己的功能实现,而不必关心其他模块的实现细节。这样不仅可以提高代码的可读性和可维护性,还可以提高编译效率,因为编译器只需要编译那些被实际引用的头文件和源文件。

虽然引用命名空间和引用头文件在C++编程中有着不同的作用,但它们在实际应用中往往是相辅相成的。例如,在一个头文件中,我们可能会定义一些属于特定命名空间的函数或类。当其他源文件需要使用这些函数或类时,它们不仅需要引用这个头文件,还需要引用相应的命名空间。这样,通过引用头文件和命名空间,我们就可以在不同的源文件之间共享和重用代码,同时避免命名冲突和简化代码书写。

综上所述,引用命名空间和引用头文件在C++编程中各有其独特的作用。引用命名空间主要用于解决命名冲突和简化代码书写,而引用头文件则主要用于实现代码重用和模块化编程。通过合理地使用它们,我们可以编写出更加高效、可读和可维护的C++代码。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手写启动类(start)

为什么要手写一个start&#xff1f; 简化代码&#xff0c;仅使用一个注解就可以实现分页功能(以下以分页为例)。 1.定义一个pageX注解 Documented Retention(RetentionPolicy.RUNTIME)//运行时可以通过反射API获取到注解信息 Target({ElementType.METHOD, ElementType.TYPE})…

redis的设计与实现(四)——单机数据库特性

1. 前言 我们前面了解了redis的数据结构&#xff0c;对象。但是redis对于这些对象的使用和管理策略需要也熟记于心&#xff0c;这篇文章我们就了解一下吧。 2. 类型检查和命令多态 DEL,EXPIRE,RENAME,TYPE,OBJECT 可以对任何数据类型执行SET,GET,APPEND,STRLEN&#xff0c;等…

【opencv】教程代码 —ImgProc (10)图像平滑处理

10. Smoothing.cpp 图像平滑处理 演示不同滤波器的效果。这些滤波器包括均值滤波、高斯滤波、中值滤波和双边滤波。每个滤波器都会在原始图像上应用&#xff0c;并显示滤波后的效果。 /*** 文件 Smoothing.cpp* 简单滤镜的样例代码* 作者 OpenCV团队*///引入所需库文件 #includ…

PL/SQL的词法单元

目录 字符集 标识符 分隔符 注释 oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 PL/SQL块中的每一条语句都必须以分号结束。 一个SQL语句可以跨多行&#xff0c;但分号表示该语句的结束:一行中也可以有多条 SQL语句&…

一周学会Django5 Python Web开发-Django5模型查询(上)

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计41条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

NLP深入学习:结合源码详解 BERT 模型(三)

文章目录 1. 前言2. 预训练2.1 modeling.BertModel2.1.1 embedding_lookup2.1.2 embedding_postprocessor2.1.3 transformer_model 2.2 get_masked_lm_output2.3 get_next_sentence_output2.4 训练 3. 参考 1. 前言 前情提要&#xff1a; 《NLP深入学习&#xff1a;结合源码详…

2024年N1叉车司机证考试题库及N1叉车司机试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年N1叉车司机证考试题库及N1叉车司机试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机出的…

串口通信标准RS232 RS485 RS422的区别

RS-232、RS-422、RS-485是关于串口通讯的一个机械和电气接口标准&#xff08;顶多是网络协议中的物理层&#xff09;&#xff0c;不是通讯协议&#xff0c;它们之间的几个不同点如下&#xff1a; 一、硬件管脚接口定义不同 二、工作方式不同 RS232&#xff1a; 3线全双工 RS…

在线教学软件推荐!一站式白板让线上教学更顺畅!

可以用于线上教学的软件&#xff0c;之前大家最为熟悉的莫过于使用各类视频会议软件&#xff0c;如腾讯会议、钉钉会议、飞书会议、Zoom 等&#xff0c;基于视频会议软件来共享电脑屏幕&#xff0c;然后再切换到本地的 PPT 演示文稿进行讲解。 但采用这个线上教学方案存在一些…

如何用磁力仪探测管缆的位置和埋深?

不论是航空磁测&#xff0c;还是海洋磁测&#xff0c;都是直接测量磁场总强度T&#xff0c;而后以总磁异常ΔT成图。磁异常总强度Ta是磁场总强度T与正常场T0的矢量差&#xff0c;即&#xff1a; Ta&#xff1d; T&#xff0d; T0 根据参考文献1&#xff0c;2的推导&#xff0c…

2024信息通信展览会|中国通信展览会|通讯大会

2024信息通信展览会|中国通信展览会|通讯大会 2024年中国国际信息通信展览会与同期举办的ICT.中国论坛于2024年9月25-27日在北京.国家会议中心隆重举办&#xff0c;共同奋力开启信息通信的新篇章。这是一场集交流、展示、共赢于一体的盛大盛典&#xff0c;为信息通信领域的企业…

保研线性代数机器学习基础复习2

1.什么是群&#xff08;Group&#xff09;&#xff1f; 对于一个集合 G 以及集合上的操作 &#xff0c;如果G G-> G&#xff0c;那么称&#xff08;G&#xff0c;&#xff09;为一个群&#xff0c;并且满足如下性质&#xff1a; 封闭性&#xff1a;结合性&#xff1a;中性…

一种重要却容易被我们忽略的能力

你有多久没有「发呆」过了&#xff1f; 我指的不是那种偶尔的走神和分心&#xff0c;而是那种持续一段时间&#xff0c;什么也不做、什么也不想&#xff0c;就这样静静站着或坐着&#xff0c;让大脑放空的状态。 可能有人会觉得&#xff1a;这太奢侈了&#xff0c;我们每天都恨…

【任职资格】某大型制造型企业任职资格体系项目纪实

该企业以业绩、责任、能力为导向&#xff0c;确定了分层分类的整体薪酬模式&#xff0c;但是每一名员工到底应该拿多少工资&#xff0c;同一个岗位的人员是否应该拿同样的工资是管理人员比较头疼的事情。华恒智信顾问认为&#xff0c;通过任职资格评价能实现真正的人岗匹配&…

基于Spring boot + Vue协同过滤算法的电影推荐系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

分享一下自己成功入职为AIGC工程师的经历

据外媒援引知情人士消息&#xff0c;OpenAI预计2023年收入将达到2亿美元&#xff0c;到2024年将达到10亿美元&#xff0c;全世界都看出了AIGC工程师的市场潜力。 而对于广大职场人士而言&#xff0c;则是意味着新的职场机遇出现了&#xff0c;学习好AIGC技术&#xff0c;无论是…

gemma 大模型(gemma 2B,gemma 7B)微调及基本使用

待整理… gemma介绍 Gemma是Google推出的一系列轻量级、最先进的开放模型&#xff0c;基于创建Gemini模型的相同研究和技术构建。提供了 2B 和 7B 两种不同规模的版本&#xff0c;每种都包含了预训练基础版本和经过指令优化的版本。所有版本均可在各类消费级硬件上运行&#x…

ThreadLocal和Synchronized的区别

目录 背景过程ThreadLocal什么是ThreadLocal&#xff1f;既然都是保证线程访问的安全性&#xff0c;那么和Synchronized区别是什么呢&#xff1f;ThreadLocal的使用TheadLocal使用场景原理高并发场景下ThreadLocal会造成内存泄漏吗&#xff1f;什么原因导致&#xff1f;如何避免…

aws 入门篇 01.aws学习的方法论

aws入门篇 01.aws学习的方法论 第1章 aws学习的方法论 aws的服务很多&#xff0c;现在应该有100多个服务了&#xff0c;怎么来学习aws呢&#xff1f; 这几年也使用了一些aws的服务&#xff0c;谈谈自己对学习aws的理解。 1.先横向&#xff0c;后纵深 比如说&#xff0c;aws最…

SpringCloud微服务集成Dubbo

1、Dubbo介绍 Apache Dubbo 是一款易用、高性能的 WEB 和 RPC 框架,同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能力、工具与最佳实践。用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服…