【C++】命名空间 ( namespace )

目录搁这

  • 什么是命名空间
    • 命名空间的作用
    • 如何定义命名空间
    • 命名空间的种类
    • 如何使用命名空间内的成员
      • 作用域限定符
      • 命名空间展开
        • 命名空间全部展开
        • 命名空间部分展开
    • 总结


什么是命名空间

命名空间是一种用来避免命名冲突的机制,它可以将一段代码的名称隔离开,使其与其他代码的名称不冲突;
在这里插入图片描述
命名空间的原理是将一个全局的作用域分成一个个命名空间,每个命名空间是个单独的作用域,同时若是在同一个作用域内可能出现的命名冲突也不会造成影响,有效避免了命名空间的污染;


命名空间的作用

在学习C语言的过程中我们知道有一个函数叫做rand函数,该函数用于生成伪随机整数;

#include<stdio.h>
int rand = 10;
int main()
{printf("%d\n",rand);return 0;
}

上面的代码在.c文件下的情况执行会得出什么结果
在这里插入图片描述

代码被运行成功且没有什么错误
但若是在包含rand函数所在的头文件为前提的结果是什么?
在这里插入图片描述

当包含了rand函数所在的头文件即报错;
原因是,在程序运行时,计算机先会在局部寻找变量,当局部内未找到时则回去全局找;
在全局找时找到了两个 rand (一个为头文件内的rand函数,一个为所创建的变量rand)
此时也不知该打印哪一个rand,这就叫命名冲突;

但在C++中,出现了一个新的概念叫做命名空间,一般来说,rand这类的函数都存放于C++中标准库类型对象的命名空间std中

若是在编译器中执行这段代码结果是什么;

#include<iostream>//标准输入输出流头文件
using namespace std;//展开标准库命名空间stdnamespace Sweet{//设置命名空间且名为Sweetint rand = 10;
}int main()
{cout << rand << endl;//打印randcout << Sweet::rand << endl;//打印Sweet中的rand(::符号为作用域限定符)return 0;
}

在这里插入图片描述

打印出来的结果没有报错,原因是在这里并没有发生命名冲突,在这段代码中使用了

namespace Sweet{int rand = 10;
}

设置了一个名为Sweet的命名空间,且在命名空间内声明变量rand,在打印过程中就相当于虽然重名但是所在班级不同的学生;

但此时的rand仍然处于全局空间中,只是隐藏在名为Sweet的命名空间内;

若是运行下面的代码,则结果是什么?

#include<iostream>using namespace std;
namespace Sweet{int rand = 10;
}
using namespace Sweet;
int main()
{cout << rand << endl;cout << Sweet::rand<<endl;return 0;
}

在这里插入图片描述
为什么上面的代码运行时并没报错而这段代码报错了?


如何定义命名空间

从上面可知命名空间的作用,既然命名空间能够有效防止命名冲突,那该如何定义命名空间

在定义命名空间时,应该使用 namespace 修饰且在该修饰词后定义名字
并在其后跟**{ }**
在{ }内的元素即为该命名空间的成员

#include<iostream>using namespace std;//展开std命名空间namespace A1 {//定义一个名为A1的命名空间int a = 0;int b = 20;//变量void Add()//函数{cout << "IsAddFunc1" << endl;}struct TestNode//结构体{int test1;double test2;};
}namespace A2 {//定义一个名为A2的命名空间int a = 10;int b = 21;void Add(){cout << "IsAddFunc2" << endl;}struct TestNode{int test3;double test4;};
}
int main()
{cout << "A1::b = " << A1::b << endl;//打印A1中的bcout << "A2::b = " << A2::b << endl;//打印A2中的bA1::Add();//调用A1中的Add函数A2::Add();//调用A2中的Add函数struct A1::TestNode AT1;//声明结构体变量struct A2::TestNode AT2;cout << &AT1 << endl;//打印结构体变量地址cout << &AT2 << endl;return 0;
}

在这里插入图片描述

从该段代码可知命名空间内不仅可以声明(定义)变量,还可以包含函数、类、typedef以及#define宏等等


命名空间的种类

在一般情况下,命名空间还可以进行嵌套,即可以在一个命名空间内嵌再嵌套命名空间,以此类推;

在这里插入图片描述

#include<iostream>
using namespace std;
namespace A1{int mi = 0;int qi = 5;namespace A2 {int qi = 10;namespace A3 {int mi = 25;}}
}
int main()
{cout << "A1::mi = " << A1::mi << endl;cout << "A1::qi = " << A1::qi << endl;cout << "A1::A2::qi = " << A1::A2::qi << endl;cout << "A1::A2::A3::mi = " << A1::A2::A3::mi << endl;return 0;
}

该处A1命名空间内嵌套着A2A2嵌套A3

在这里插入图片描述

注意: 命名空间只能在全局范围定义!!

在这里插入图片描述

故上图的使用方法为错误方法

如何使用命名空间内的成员

既然命名空间可以防止发生命名冲突,那放在命名空间的成员应该如何使用?

作用域限定符

在一般情况下,若是想使用命名空间内的成员,可以使用作用域限定符 ::(域解析操作符)

#include<iostream>
using namespace std;
namespace A1{int mi = 0;int qi = 5;namespace A2 {int qi = 10;namespace A3 {int mi = 25;}}
}
int main()
{cout << "A1::mi = " << A1::mi << endl;cout << "A1::qi = " << A1::qi << endl;cout << "A1::A2::qi = " << A1::A2::qi << endl;cout << "A1::A2::A3::mi = " << A1::A2::A3::mi << endl;return 0;
}

该段代码即使用了作用域限定符;

该符号的作用是通知编译器应从作用域限定符左侧的名字所示的作用域中寻找右侧那个名字,即指定访问哪个名字空间的哪个成员。


命名空间展开

除了可以使用作用域限定符进行操作以外还可以将命名空间展开,同时命名空间展开有两种

命名空间全部展开

命名空间部分展开

命名空间全部展开

命名空间全部展开需要使用

cpp using namespace xxx;
进行修饰;

#include<iostream>
using namespace std;
int main()
{cout<<"using namespace std"<<endl;return 0;
}

如上代码将标准库中的std命名空间展开,即可以在不受作作用域限定符的限制使用std命名空间内的coutendl

但若是将命名空间全部展开则也有一些麻烦;
例如:
在这里插入图片描述

该处将两个命名空间都进行了展开,导致程序在运行中从全局范围中找到了两个rand从而导致的“悲剧”;

故一般情况下,在项目中不支持以命名空间全部展开的方式使用命名空间内的成员;

命名空间部分展开

除了命名空间全部展开以外还有一种方式即相对的进行命名空间部分展开;

 using XXX :: xxx;

以该方式将命名空间中的部分分支进行展开,即可以在不全部展开以及不使用作用域限定符的情况下使用命名空间内的成员;

#include<iostream>using std::cout;//进行命名空间部分展开将std命名空间内的cout以及endl进行部分展开
using std::endl;//命名展开后可以在不影响该命名空间以内其他成员的情况下使用cout与endlint main()
{cout << "Hello World" << endl;//打印"Hello World"return 0;
}

总结

命名空间可以避免命名冲突问题;
命名空间可以进行嵌套;
命名空间必须在全局范围内定义,不可再局部范围内定义;
在使用命名空间内的成员时共有三种方法(作用域限定符、命名空间全部展开、命名空间部分展开),在一般练习中尽量不要进行全部展开;

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

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

相关文章

纯CSS实现的卡片切换效果

纯CSS实现的卡片切换效果 无需JS就可以实现限于纯静态页面产品展示不需要轮播,自动切换 示例代码 <template><div class"example-css-tab"><div class"container dwo"><div class"card"><input type"radio"…

【实战总结】SpringMVC架构升级SpringCloudAlibaba

升级目标 SpringMVCDubboZookeeper分布式架构改为Spring Cloud Alibaba微服务 技术框架:Spring Boot 2.7.2、Spring Cloud 2021.0.3 & Alibaba 2021.0.1.0 容器:Tomcat 9.0.65 JDK:1.8 配置中心:Nacos 2.0.4 消息队列:RocetMQ 4.9.3 配置中心:Apollo 11.0 缓存: Redis 4.0…

【C语言】杨氏矩阵中寻找元素

题目名称&#xff1a; 杨氏矩阵 题目内容&#xff1a; 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从下到上递增的&#xff08;杨氏矩阵的定义&#xff09;&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 形如这样的矩阵就是杨氏…

chatglm微调

chatGML 看到 【【官方教程】ChatGLM-6B 微调&#xff1a;P-Tuning&#xff0c;LoRA&#xff0c;Full parameter】 【精准空降到 15:27】 https://www.bilibili.com/video/BV1fd4y1Z7Y5/?share_sourcecopy_web&vd_sourceaa8c13cff97f0454ee41e1f609a655f1&t927 记得看…

一文了解Docker之网络模型

目录 1.Docker网络 1.1 Docker网络模型概述 1.2 Docker网络驱动程序 1.2.1 host模式 1.2.2 bridge模式 1.2.3 container模式 1.2.4 none模式 1.3 Docker网络命令示例 1.3.1 创建一个自定义网络 1.3.2 列出所有网络 1.3.3 连接容器到网络 1.3.4 断开容器与网络的连接…

SpringCloud(三)LoadBalancer负载均衡

一、负载均衡 实际上&#xff0c;在添加LoadBalanced注解之后&#xff0c;会启用拦截器对我们发起的服务调用请求进行拦截&#xff08;注意这里是针对我们发起的请求进行拦截&#xff09;&#xff0c;叫做LoadBalancerInterceptor&#xff0c;它实现ClientHttpRequestIntercep…

Android 系统的分区介绍

由于Android系统采用Linux架构&#xff0c;所以Android的系统分区可以类比同样采用Linux架构的操作系统&#xff08;如Windows&#xff09;。 Android系统分区分类 现在一般常见的Android分区方式共有三种&#xff0c;在不同的Android系统版本上会采用不同的分区方式。 1、传…

Postman接口自动化之postman脚本编写

这是之前搞的接口自动化方案&#xff0c;已经在业务测试中实现了使用postman编写接口脚本&#xff0c;通过GitHubJenkinsemail html report实现了接口自动化&#xff0c;现在分块整理一下。 postman脚本编写 1、创建集合 和 目录&#xff1a; 一条业务线下的接口可以放到一个…

sonarqube安装并配置CI/CD

sonarqube安装使用 目录 简介效果(配置在下面查看)官方文档环境准备配置compose-sonarqube.yml启动登录集成Gitlab 获取私钥sonarqube配置gitlab查看项目 配置 手动方式Gitlab CI/CD 自动检测 简介 SonarQube是一个开源的代码质量管理平台&#xff0c;用于对代码进行静态代…

【数学建模】——相关系数

第一部分&#xff1a;皮尔逊相关系数的计算以及数据的描述性统计 本讲我们将介绍两种最为常见的相关系数&#xff1a;皮尔逊person相关系数和斯皮尔曼spearman等级相关系数。它们可以用来衡量两个变量之间的相关性的大小&#xff0c;根据数组满足的不同条件&#xff0c;我们要选…

Monocular 3D Object Detection with Depth from Motion 论文学习

论文链接&#xff1a;Monocular 3D Object Detection with Depth from Motion 1. 解决了什么问题&#xff1f; 从单目输入感知 3D 目标对于自动驾驶非常重要&#xff0c;因为单目 3D 的成本要比多传感器的方案低许多。但单目方法很难取得令人满意的效果&#xff0c;因为单张图…

QT之智能指针

如果没有智能指针&#xff0c;程序员必须保证new对象能在正确的时机delete&#xff0c;四处编写异常捕获代码以释放资源&#xff0c;而智能指针则可以在退出作用域时(不管是正常流程离开或是因异常离开)总调用delete来析构在堆上动态分配的对象。 来看看一个野指针例子 程序将会…

java学习路程之篇三、知识点、类、模块、项目、操作、下载、安装、IDEA

文章目录 1、IDEA开发工具2、IDEA的下载和安装3、IDEA中的第一个代码4、IDEAZ中的类、模块、项目的操作 1、IDEA开发工具 2、IDEA的下载和安装 3、IDEA中的第一个代码 4、IDEAZ中的类、模块、项目的操作

【计算机视觉 | 图像分类】arxiv 计算机视觉关于图像分类的学术速递(7 月 17 日论文合集)

文章目录 一、分类|识别相关(11篇)1.1 Multimodal Distillation for Egocentric Action Recognition1.2 Dual-Query Multiple Instance Learning for Dynamic Meta-Embedding based Tumor Classification1.3 Interactive Spatiotemporal Token Attention Network for Skeleton-…

基于ClickHouse解决活动海量数据问题 | 京东云技术团队

1、背景 魔笛活动平台要记录每个活动的用户行为数据&#xff0c;帮助客服、运营、产品、研发等快速处理客诉、解决线上问题并进行相关数据分析和报警。可以预见到需要存储和分析海量数据&#xff0c;预估至少几十亿甚至上百亿的数据量&#xff0c;所以需要选择一款能存储海量数…

会议音响系统麦克风阵列波束形成算法C语言实现

一 应用麦克风阵列波束成形算法做的项目产品 二 麦克风波束形成技术应用领域? 麦克风波束形成技术是一种利用多个麦克风阵列来实现声音定向捕捉和增强的技术。通过对多个麦克风信号进行处理和合成,可以使麦克风系统在特定方向上具有更高的灵敏度和抑制非期望方向上的噪…

机器学习(13)--支持向量机

目录 一、支持向量机概述 二、Sklearn中的SVM概述 三、线性SVM损失函数 四、sklearn中进行可视化 1、导入模块 2、实例化数据集&#xff0c;可视化 3、网格点制作 4、建立模型并绘制决策边 目录 一、支持向量机概述 二、Sklearn中的SVM概述 三、线性SVM损失函数 四…

机器学习技术(三)——机器学习实践案例总体流程

机器学习实践案例总体流程 文章目录 机器学习实践案例总体流程一、引言二、案例1、决策树对鸢尾花分类1.数据来源2.数据导入及描述3.数据划分与特征处理4.建模预测 2、各类回归波士顿房价预测1.案例数据2.导入所需的包和数据集3.载入数据集&#xff0c;查看数据属性&#xff0c…

四个按键控制led的四种变化(按键控制led)(附源码)

文章目录 一、实验任务二、系统框图三、代码实现四、引脚分配五、总结 一、实验任务 使用开发板上的四个按键控制四个LED灯。按下不同的按键时&#xff0c;四个LED灯显示不同效果。本实验是在EP4CE6F17C8开发板上实现&#xff0c;仿真请用modelsim Altera 二、系统框图 三、代…

揭秘GPT-4;Adobe Firefly AI 扩大测试规模

&#x1f989; AI新闻 &#x1f680; Adobe Firefly AI 扩大测试规模&#xff0c;支持100多种语言的输入 摘要&#xff1a;Adobe宣布扩大测试规模&#xff0c;Adobe Firefly AI现在支持100多种语言的 prompts 输入。网页测试版Firefly已经扩充了罗马尼亚语等多种语言&#xf…