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

news/2024/5/14 21:41:28

命名空间

  • 前言
  • 一、命名空间
    • 引例
    • 什么是命名空间
  • 二、命名空间定义
    • 正常的命名空间定义
    • 嵌套的命名空间
    • 多个相同名称的命名空间
  • 三、命名空间使用
    • 加命名空间名称及作用域限定符
    • 使用`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++代码。



http://www.mrgr.cn/p/25743344

相关文章

腾讯云Ubuntu远程接入Vscode并设置root免密码登录

最近在尝试Linux编程,想起自己还有一个腾讯云的服务器,就重装了Ubuntu,然后装了环境之后尝试用Vscode连接,但是发现用root用户无论如何都登录不上,后来把用户名换成ubuntu之后就能登录上了,但是在VsCode上写代码时又出现了很多问题。 1、某些文件夹打不开,后来发现是用户…

LeetCode每日一题——移除链表元素

移除链表元素OJ链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 这与之前的移除元素的题目很相似&#xff0c;那么我们同样可以用类似的做法&#xff08;双指针&#xff09;进行解题。但是这是一个链表删除&a…

element-ui checkbox 组件源码分享

简单分享 checkbox 组件&#xff0c;主要从以下三个方面来分享&#xff1a; 1、组件的页面结构 2、组件的属性 3、组件的方法 一、组件的页面结构 二、组件的属性 2.1 value / v-model 属性&#xff0c;绑定的值&#xff0c;类型 string / number / boolean&#xff0c;无…

java注解的实现原理

首先我们常用的注解是通过元注解去编写的&#xff0c; 比如&#xff1a; 元注解有Target 用来限定目标注解所能标注的java结构&#xff0c;比如标注方法&#xff0c;标注类&#xff1b; Retention则用来标注当前注解的生命周期&#xff1b;比如source&#xff0c;class&…

后处理 - 均值模糊

原理 就是取自身以及该像素周围的8个像素的颜色值相加,然后除9取个平均值,得到最终颜色值效果因为模糊后会出现一些方形的像素效果,模糊效果不是很平均,所以均值模糊也叫做盒状模糊。c#代码using UnityEngine;public class BoxBlurEff : MonoBehaviour {public Shader m_Sh…

星云小窝项目1.0——项目介绍(一)

星云小窝项目1.0——项目介绍&#xff08;一&#xff09; 文章目录 前言1. 介绍页面2. 首页2.1. 游客模式2.2. 注册用户后 3. 星云笔记3.1. 星云笔记首页3.2. 星云笔记 个人中心3.2. 星云笔记 系统管理3.3. 星云笔记 文章展示3.3. 星云笔记 新建文章 4. 数据中心5. 交流评论6. …

[OSS] 对象存储(OSS)概述

0 序本文属笔记型博文。目标读者:博主本人本文OSS的描述内容,主要参考阿里云的OSS产品。1 对象存储-概述 1.1 什么是对象存储OSS?对象存储服务(Object Storage Service)是阿里云等云平台提供的海量、安全、低成本、高可靠的云存储服务,提供与平台无关的RESTful API接口,…

[SpringMVC]知识点

本篇文章是关于SpringMVC各类知识点的小结,例如:restful风格、自定义异常处理器等。 如果文中阐述不全或不对的,多多交流。【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18032069 出自【进步*于辰的博客】目录…

初始xpath

包的安装 pip install lxml谷歌浏览器插件安装 XPath Helper 可以自行搜索安装也可以点击: 传送门 解析流程与使用实例化一个etree的对象,把即将被解析的页面源码加载到该对象。 调用该对象的xpath方法结合着不同形式的xpath表达式进行标签定位和数据提取# 导入lxml.etree f…

HDFS的Shell操作及客户端配置方法

HDFS进程启停命令 Hadoop HDFS组件内置了HDFS集群的一键启停脚本。 $HADOOP_HOME/sbin/start-dfs.sh&#xff0c;一键启动HDFS集群$HADOOP_HOME/sbin/stop-dfs.sh&#xff0c;一键关闭HDFS集群 执行原理&#xff1a; 在执行此脚本的机器上&#xff0c;启动&#xff08;关闭&…

处理登录失效后提示多个错误

问题: 我的场景是后端规定&#xff0c;即使登录失效返回的code仍是200&#xff0c;然后data的code是999什么的&#xff1b; 原本代码&#xff1a; 修改版代码&#xff1a; 通过节 const NotLoginEvent () > {router.replace("/login");localStorage.clear();M…

炒股技术整理系列:金针探底 雪迪龙 2024-02-06

特征: 1、大幅度下跌,大幅度是什么程度? 3个月最高点到最低点 跌了48%,,从确认趋势一个月内,跌了30%。 2、长下影线。涨幅不超过1%。 3、第二天或第三天收大幅阳线,已站上5日线 4、第四天可以买入。不跌破最后一根大阴线的中间段,可一直拿着。翻译 搜索 复制

自定义的基于System.Net.Http.HttpClient的WebClient,可以作为微信支付宝的发起请求时的基础请求类

个人编写的,自己用于自己的微信api的请求的实现当中,源码公开,大家可以查看反编译源码。以下是使用方法: 第一步 搜索和安装zmjtool第二步 发起请求1 /**引入命名空间*/2 using ZmjTool;3 4 /**发起Get请求*/5 using (var cl = new ZmjTool.WebClient())6 {7 cl.Handle…

mysql80-DBA数据库学习1-数据库安装

掌握能力 核心技能 核心技能 mysql部署 官网地址www.mysql.com 或者www.oracle.com https://dev.mysql.com/downloads/repo/yum/ Install the RPM you downloaded for your system, for example: yum install mysql80-community-release-{platform}-{version-number}.noarch…

地铁查询app 结对作业三

经过今天一下午的奋斗 安卓app 只剩下最难的部分了 最短路径问题 我们考虑用迪杰斯特拉算法 不过 没有做出来 还要继续去学习一下这个代码 并寻求网上代码的帮助

解决跨域问题

代码量:100 博客:1 我们使用的是niginx 解决跨域问题,其实我上网搜索了很多niginx跨域的代码,但是不知道怎么使用放在哪里,刚才经过同学的帮助成功知道啦,下面展示一下路径的图片 这里的nginx.exe是启动,shutdown是自己写的可以快速关闭程序

数据库管理开发工具Navicat for MySQL Mac版下载

Navicat for MySQL&#xff08;Mac版&#xff09;是一款强大的数据库管理开发工具&#xff0c;专为MySQL设计。它提供直观的用户界面&#xff0c;支持数据建模、查询构建、数据传输等功能&#xff0c;帮助用户轻松管理数据库。其特点包括高效的数据处理能力、安全的数据传输机制…

文本数据处理

文本数据处理 情无论巨细,往往存在一个准备阶段。比如做饭炒菜,需要择菜、洗菜、切菜、热锅等准备工作;出远门需要整理好身份证、手机、钱包等随身物品。类似地,在处理文本的任务中,也存在预处理这么一个重要阶段,包括诸如统一数据格式、去噪、词形还原、分词之类的基本操…

UG NX二次开发(C#)-通过曲线组生成NURBS曲面

文章目录 1、前言2、UG NX中通过曲线组生成NURBS曲面的操作3、采用NXOpen C#方法的源代码1、前言 在UG NX中,曲线、曲面的操作使用比较多,对于创建NURBS曲面,可以通过曲线组来生成,本文以NXOpen C#的方法实现通过曲线组生成NURBS曲面的功能。对于UG NX二次开发感兴趣或者有…