命名冲突问题与命名空间
一、何为命名空间?
首先我们运行下面代码,
#include <stdio.h>
int rand = 0;
int main()
{printf("%d", rand);return 0;
}
我们会发现该代码能够正常运行,没有任何问题。
但是当我们再在上面代码的基础上包含stdlib.h头文件,代码还能正常运行吗?
#include <stdio.h>
#include <stdlib.h>
int rand = 0;
int main()
{printf("%d", rand);return 0;
}
这时我们会发现代码报错——“rand”重定义。这是因为在stdlib.h头文件中已经定义了rand()函数,与全局变量rand发生了命名冲突问题,从而导致printf()函数无法确定是输出rand全局变量的值还是输出rand()函数的地址。
在日常写代码的过程中,我们自己定义的变量、函数很有可能跟C++库发生命名冲突问题。并且进入公司项目组以后,做的项目通常比较大,多人协作也很有可能造成命名冲突问题。
但是C语言没有办法很好地解决这个问题,若非要有办法的话,也就只能是给重名的定义更换其他名字。
但这样做会导致工作效率十分低下,为了更高效地解决此问题,C++提出了一个新语法——命名空间。
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
二、命名空间定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
如下面代码:
#include <stdio.h>
#include <stdlib.h>namespace zjd // zjd为命名空间的的名称
{int rand = 0;
}int main()
{
// rand先到局部范围内找,若没有再到全局范围内找,若还没有则程序会报错,不会到定义的域里面去找printf("%d\n", rand); // rand访问的是全局变量,rand()函数// rand指定到定义的zjd域里面去找printf("%d\n", zjd::rand); // ::域作用限定符return 0;
}
该代码定义了一个名为zjd的命名空间(域),与全局作用域进行了隔离,不会发生命名冲突问题。
Note:
①命名空间定义和结构体定义写法类似但又不同,结构体定义了一个新的数据类型,命名空间定义了一个新的域。
②域作用限定符(::)
当域作用限定符(::)前面指定域名时,会到指定的域中寻找变量、函数和类。
当域作用限定符(::)前面为空白时,会到全局域中寻找变量、函数和类。
当没有域作用限定符(::)前面指定域名时,会依次到局部域、全局域中寻找变量、函数和类。若局部域和全局域都没有找到,程序会报错。
int a = 0; int main() {int a = 1;printf("%d\n", a); // 输出局部变量a —— 1printf("%d\n", ::a); // 输出全局变量a —— 0return 0; }
③一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。
1、普通的命名空间
命名空间中的内容,既可以定义变量,也可以定义函数,还可以定义类型。
namespace N1
{int rand; // 变量int Add(int left, int right) // 函数{return left + right;}struct Node // 类型{struct Node* next;int val;};
}int main()
{N1::a = 10;printf("%d\n", N1::a);int sum = N1::Add(1, 2);printf("%d\n", sum);struct N1::Node node;return 0;
}
2、命名空间可以嵌套
命名空间内部还可以嵌套定义命名空间。
namespace N2
{int a;int b;int Add(int left, int right){return left + right;}namespace N3{int c;int d;int Sub(int left, int right){return left - right;}}
}int main()
{int sum = N2::Add(1, 2);printf("%d\n", sum);int dif = N2::N3::Sub(2, 1);printf("%d\n", dif);return 0;
}
3、多个命名空间名称相同
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
比如一个工程中的test.h和test.cpp中两个同名的命名空间会被合并成一个。
// Test.h
namespace N4
{typedef struct ListNode{struct ListNode* next;int val;}ListNode, * LinkList;void ListInit(LinkList ps); // 声明void ListPushBack(LinkList ps, int x); // 声明
}// Test.cpp
#include"Test.h"
namespace N4
{void ListInit(LinkList ps) // 定义{// 实现不展开写了}void ListPushBack(LinkList ps, int x) // 定义{// 实现不展开写了}
}int main()
{struct N4::ListNode node;N4::ListInit(&node);N4::ListPushBack(&node, 3);return 0;
}
三、命名空间使用
命名空间中成员该如何使用呢?比如下面代码是正确的代码吗?
namespace N
{int a = 10;int b = 20;int Add(int left, int right){return left + right;}int Sub(int left, int right){return left - right;}
}
int main()
{printf("%d\n", a); // 该语句编译出错,无法识别areturn 0;
}
由于局部域和全局域都没有a,并且未通过域作用限定符指定a的域,无法识别a,所以上面代码无法正常运行。
命名空间的使用有三种方式:
- 加命名空间名称及作用域限定符
- 使用using将命名空间中成员引入
- 使用using namespace 命名空间名称引入
1、加命名空间名称及作用域限定符
在命名空间定义的讲解中,大家实际上已经掌握该方式的使用了。
namespace N
{int a = 10;int b = 20;int Add(int left, int right){return left + right;}int Sub(int left, int right){return left - right;}
}int main()
{printf("%d\n", N::a);return 0;
}
Note:该方式能够做到最好的命名隔离,但是使用不方便,每次都需要指定域。
2、使用using将命名空间中成员引入
通过该方式我们可以将命名空间的某个成员展开,被展开的成员无需再通过域作用限定符指定域,但是未被展开的成员仍需要通过域作用限定符指定域。
namespace N
{int a = 10;int b = 20;int Add(int left, int right){return left + right;}int Sub(int left, int right){return left - right;}
}using N::b;int main()
{printf("%d\n", N::a);printf("%d\n", b);return 0;
}
Note:该方式可以用于展开常用的成员,也有较好的隔离效果。
3、使用using namespace 命名空间名称引入
通过该方式我们可以将整个命名空间展开,使用该命名空间里的变量、函数等无需再通过域作用限定符指定域了。
namespace N
{int a = 10;int b = 20;int Add(int left, int right){return left + right;}int Sub(int left, int right){return left - right;}
}using namespace N;int main()
{printf("%d\n", a);printf("%d\n", b);Add(10, 20);return 0;
}
Note:命名空间全部展开,用起来虽然极其方便,但是隔离彻底失效了。这种方式建议大家慎用。
相关文章:
命名冲突问题与命名空间
一、何为命名空间? 首先我们运行下面代码, #include <stdio.h> int rand 0; int main() {printf("%d", rand);return 0; } 我们会发现该代码能够正常运行,没有任何问题。 但是当我们再在上面代码的基础上包含stdlib.h头…...

Kafka漏洞修复之CVE-2023-25194修复措施验证
Kafka漏洞修复之CVE-2023-25194修复措施验证前言风险分析解决方案AdoptOpenJDK Zookeeper Kafka多版本OpenJDK安装切换Zookeeper安装Kafka安装与使用其他Kafka消息发送流程Linux配置加载顺序参考链接前言 场景介绍 Kafka最近爆出高危漏洞CNNVD-202302-515,导致Apa…...
中后序遍历构建二叉树与应用I
目录 题目描述 思路分析 AC代码 题目描述 按中序遍历和后序遍历给出一棵二叉树,求这棵二叉树中叶子节点权值的最小值。 输入保证叶子节点的权值各不相同。 输入 测试数据有多组 对于每组测试数据,首先输入一个整数N (1 < N < 10000)&#x…...
随机退化模型--基础篇(1)
随机退化模型--基础篇(1) 1. 随机退化建模1.1 瞬间失效1.2 存在缓慢退化过程的失效2. 通俗解释2.1 包引入2.2 参数定义2.3 基于递归函数的更新2.4 结果可视化1. 随机退化建模 随机模型亦称“非确定的、概率的模型”,是按随机变量建立的模型。其特点是; 模型参数、模拟对象发…...

2023.2.15工作学习记录 git Docker compose容器编排
关于Git错误提交了target目录 是因为在ignore目录中没有加入biz这个工程 以后提交代码时一定要检查好自己提交的代码 首先把所有的全部取消 然后再根据自己要提交的内容一个个来勾选 Docker网络 container模式:新建的容器和已经存在的一个容器共享一个网络…...

基于jeecgboot的flowable流程增加节点自动跳过功能
为了满足有时候需要在某个节点没有人员处理的时候需要自动跳过,所以增加了这个功能。 一、FlowComment意见里增加一个类型8,跳过流程 /** * 流程意见类型 * */ public enum FlowComment { /** * 说明 */ NORMAL("1", "…...

流程引擎之Activiti简介
背景Activiti 是一个开源架构的工作流引擎,基于 bpmn2.0 标准进行流程定义,其前身是 jBPM,Activiti 相对于 jBPM 更轻量,更易上手,且天然集成了 Spring。2010年 jBPM 创始人 Tom Baeyens 离开 JBoss,随之加…...

4.打包子应用 投票
接上回 最终得到这样的目录 mysite/manage.pymysite/__init__.pysettings.pyurls.pyasgi.pywsgi.pypolls/__init__.pyadmin.pyapps.pymigrations/__init__.py0001_initial.pymodels.pystatic/polls/images/background.gifstyle.csstemplates/polls/detail.htmlindex.htmlresult…...
华为OD机试 - 服务依赖(JavaScript) | 机试题算法思路 【2023】
服务依赖 题目 在某系统中有众多服务,每个服务用字符串(只包含字母和数字,长度<=10)唯一标识,服务间可能有依赖关系,如A依赖B,则当B故障时导致A也故障。 传递具有依赖性,如A依赖B,B依赖C,当C故障时导致B故障,也导致A故障。给出所有依赖关系以及当前已知故障服务…...

目标检测综述(一份全的自制PPT): 涵盖各种模型简介对比,适合入门和了解目标检测现状
[TOC](目标检测综述(一份全的自制PPT): 涵盖各种模型简介对比,适合入门和了解目标检测现状) 注:本文仅供学习,未经同意勿转。分享的PPT请勿二次传播,或者用于其他商用途径。若使用本文PPT请注明来源,感谢配合 前言&…...

Vulnhub-DC-2实战靶场
Vulnhub-DC-2实战靶场 https://blog.csdn.net/ierciyuan/article/details/127560871 这次试试DC-2,目标是找到官方设置的5个flag。 一. 环境搭建 1. 准备工具 虚拟机Kali: 自备,我的kali的IP为192.168.3.129 靶场机: https…...

从输入URL到渲染的过程中到底发生了什么?
CDN缓存DNSTCP三次握手、四次挥手浏览器渲染过程输入URL到页面渲染过程的一些优化 下面我将“从输入URL到渲染的全过程”大概的描述出来,再对其过程加以解释,了解过程中可以做哪些优化。文章内容有点长,需要有足够的耐心看完哟!&…...
旋转屏幕导致 Fragment 中的 onConfigurationChanged 被调用两次
环境 IDE Android Studio Dolphin 2021.3.1; 项目配置 Android Gradle plugin version: 7.1.3 Gradle Version: 7.2 Gradle JDK: 11 Compile Sdk Version: 32 问题描述 项目使用的 Bottom Navigation Activity 基本结构,在调试程序时发现,…...

23年校招DL/NLP/推荐系统/ML/算法基础面试必看300问及答案
2020年校招已经开始了,在疫情全球肆虐的背景下,全球就业情况异常艰难,加上美国对中国企业打压持续升级,对于马上开始秋招找工作的毕业生而言,更是难上加难。我们不能凭一己之力改变现状,但我们可以凭借自己…...
Python基础知识汇总(字符串二)
目录 检索字符串 count()方法 find()方法 in关键字 index()方法 rindex()方法 startswith()方法...

【FPGA】Verilog:实现十六进制七段数码管显示 | 7-Segment Display
写在前面:本章主要内容为理解七点数码管显示的概念,并使用 Verilog 实现。生成输入信号后通过仿真确认各门的动作,通过 FPGA 检查在 Verilog 中实现的电路的操作。 Ⅰ. 前置知识 七段数码管是利用多重输出功能的非常有用的元件。该元件用于字…...

Android开发:Activity启动模式
1.怎样设置Activity的启动模式 可以在清单文件中自己添加活动的启动模式, android : launchMode"standard", 不写的话系统默认就是标准模式. 2.启动模式 2.1.默认启动模式 标准启动模式就是栈, 打开一个活动就将活动压入栈中, 返回就将活动退出栈中. 不同的Activit…...

01_Docker 简介
01_Docker 简介 文章目录01_Docker 简介1.1 Docker 简介1.2 Docker 组件1.2.1 Docker 客户端和服务区1.2.2 Docker 镜像1.2.3 Registry1.2.4 Docker 容器参考资料https://www.runoob.com/docker/ubuntu-docker-install.html 1.1 Docker 简介 Docker 是一个能够把开发的应用程…...

一文精通MVCC机制
MVCC(Multi-Version Concurrency Control)多版本并发控制机制使用串行化隔离级别时,mysql会将所有的操作加锁互斥,来保证并发安全。这种方式必然降低并发性能。mysql在读已提交和可重复读隔离级别下,对一行数据的读和写两个操作默认是不会通过…...
商用ESP32协议采集器源码分享开篇
这是一个关于chatGPT帮助嵌入式程序员开发商业项目的故事. 在开发这个项目的过程中,chatGPT发布了,在它的帮助下,项目开发量减少了10%,所以这个专栏,既是一个关于Micropython开发ESP32的专栏,也是一个程序员在AI的帮助下,提升效率,加速挣钱的案例. 看完之后,你将知道如何用mic…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...