【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,一经查实,立即删除!

相关文章

对学习方法的一些思考

只看基金的招募书和合同的只言片语是没办法彻底的了解这只基金的策略的&#xff0c;必须有一个机会看看基金经理是怎么聊这个策略的&#xff01; 基金这个壳子的【股票/债券】究竟应该如何配比才能达到理想且优秀的效果呢&#xff1f; 【债券配得多从长期&#xff08;5年&#…

纯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…

Elasticsearch 查询分析器简介

Elasticsearch 查询分析器简介 一、Elasticsearch 查询分析器概述1.1 Elasticsearch 简介1.2 查询分析器的作用 二、查询分析器类型2.1 Standard Analyzer2.2 Simple Analyzer2.3 Whitespace Analyzer2.4 Stop Analyzer2.5 Keyword Analyzer2.6 Pattern Analyzer2.7 语言分析器…

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

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

[USACO21DEC] Convoluted Intervals S

洛谷[USACO21DEC] Convoluted Intervals S 题目大意 有 n n n个区间&#xff0c;第 i i i个区间为 [ a i , b i ] [a_i,b_i] [ai​,bi​]&#xff0c;都在 [ 0 , m ] [0,m] [0,m]上。对于每一个 k ∈ [ 0 , 2 m ] k\in [0,2m] k∈[0,2m]&#xff0c;求满足 a i a j ≤ k ≤ …

关于贪心算法的一个小结

下面的内容主要参考了数据结构与算法之美。 贪心算法的应用有&#xff1a; 霍夫曼编码&#xff08;Huffman Coding&#xff09; Prim和Kruskal最小生成树算法 01背包问题(当允许取部分物品的时候) 分糖果 我们有m个糖果和n个孩子。我们现在要把糖果分给这些孩子吃&#xff…

MySQL是否解决幻读问题

MySQL是否解决幻读问题 MySQL事务隔离级别 ✓ 读未提交&#xff08;Read Uncommitted&#xff09;&#xff1a;最低的隔离级别&#xff0c;会读取到其他事务还未提交的内容&#xff0c;存在脏读。 ✓ 读已提交&#xff08;Read Committed&#xff09;&#xff1a;读取到的内容都…

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 记得看…

npm 加速 国内镜像源

一、修改成腾讯云镜像源 1、命令 npm config set registry http://mirrors.cloud.tencent.com/npm/ 验证命令 npm config get registry 如果返回http://mirrors.cloud.tencent.com/npm/&#xff0c;说明镜像配置成功。 二、修改成淘宝镜像源 命令 npm config set regist…

一文了解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; 一条业务线下的接口可以放到一个…

Android adb说明与详解

Android adb 说明与详解 Android Debug Bridge&#xff08;ADB&#xff09;是一个非常有用的工具&#xff0c;它可以帮助开发人员在Android设备和计算机之间进行通信&#xff0c;以便在设备上进行调试、测试和安装应用程序。 1. 安装ADB 在使用ADB之前&#xff0c;您需要安装…

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来析构在堆上动态分配的对象。 来看看一个野指针例子 程序将会…

封装React组件DragLine,鼠标拖拽的边框改变元素宽度

原文合集地址如下&#xff0c;有需要的朋友可以关注 本文地址 合集地址 在项目中&#xff0c;设计说想做个面板&#xff0c;其宽度随鼠标拖拽而变化&#xff0c;有最大最小值。基于这个小功能封装一个可拖拽组件&#xff0c;在需要的地方引入即可。 思路 这里只是实现x方向…