C++ —— 命名空间

news/2024/4/28 2:30:39/文章来源:https://blog.csdn.net/m0_64240499/article/details/126868293

文章目录

  • 命名空间的由来
  • 什么是命名空间
  • 命名空间的定义
  • 同名的命名空间的合并
  • 域作用限定符
  • 命名空间的三种使用方法
  • 头文件与std
  • 命名空间的本质


命名空间的由来

我们先来看看下面这段代码,看看能不能编译成功:

//此时文件后缀为.c
#include<stdio.h>int rand = 10;
int main()
{printf("%d\n", rand);return 0;
}

这么一看,好像确实没有什么问题?实际上编译器也能成功编译过去。
在这里插入图片描述

但如果加上下面的头文件呢?

#include<stdio.h>
#include<stdlib.h>//新加的头文件int rand = 10;
int main()
{printf("%d\n", rand);return 0;
}

结果却是失败的,因为在预处理阶段,stdlib这个头文件会进行展开,而其中就有一个名为rand的函数,展开后该函数同样位于全局区,这就与我们定义的rand变量有名字冲突;
在这里插入图片描述
由于这种情况(自己定义的变量名或函数名与其他人的冲突)在大型项目中经常出现,C++就提出了域名空间这么一个概念;

什么是命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都将存在于全局作用域中,可能会导致很多冲突。适用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或者名字污染,namespace关键字的出现就是针对这种问题的。命名空间相当于一堵围墙,将内部成员与全局域成员隔离开来;

命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员;
命名空间的成员可以是变量,可以是函数,也可以是结构体:

namespace zjm
{int rand = 10;int Add(int x, int y){return x + y;}struct Node{struct Node* next;int val;};
}

命名空间也可以嵌套使用:

namespace zjm
{int x = 30;namespace zs{int z = 200;int Sub(int x, int y){return x - y;}}
}

既然命名空间可以将内部成员与全局域成员隔离开来,那么利用命名空间我们就可以解决上面代码中的名字冲突问题:

//此时文件后缀为.cpp
#include<stdio.h>
#include<stdlib.h>namespace zjm
{int rand = 10;
}int main()
{printf("%d\n", zjm::rand);//访问指定命名空间中的成员printf("%p\n", rand);//访问全局变量return 0;
}

在这里插入图片描述

同名的命名空间的合并

同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间;
例如:test.h 会与 test.cpp中的同名域进行合并

//test.h
namespace zjm
{int Add(int x, int y){return x + y;}
}//test.c
#include"test.h"//必须包含头文件
namespace zjm
{int x = 30;namespace zs{int z 200;int Sub(int x, int y){return x - y;}}
}
//最终test.h和test.c中zjm命名空间会合并

在这里插入图片描述
在这里插入图片描述
注意:
在同一个文件中如果出现多个同名域,也是会进行合并的;如果在两个 .cpp文件中出现同名域,在逻辑上也是会合并的,但如果要使用,就必须进行声明;如下:

//test1.cpp
namespace zjm
{int Add(int x, int y){return x + y;}
}//test2.cpp
namespace zjm
{int Add(int x, int y);//进行函数声明int Sub(int x, int y){return x - y;}
}

域作用限定符

在上述代码中,:: 为域作用限定符,其作用是:访问指定域中的成员,如果域中没有该成员则报错; 其使用规则是:左边带命名空间的名字,右边带命名空间中的成员;
注意:
如果域作用限定符左边没有加名字,则表示指定到全局域中去寻找

int x = 0;int main()
{int x = 1;printf("%d\n", ::x);//指定到全局域中寻找printf("%d\n", x);//访问局部变量优先return 0;
}

在这里插入图片描述

命名空间的三种使用方法

namespace N
{int a = 10;int b = 20;int Add(int x, int y){return x + y;}
}

1.加命名空间名称与域限定符

printf("%d\n",N::a);

2.使用using将某个空间中某个成员引入

using N::b;//此时b就会有与全局域成员同名的风险
printf("%d\n",N::a);//由于没有引入a,所以仍然需要加域限定符
printf("%d\n",b);

3.使用using namespace将整个命名空间名称引入

using namespace N;//此时N中的成员就会有与全局域中成员同名的风险
printf("%d\n",a);
printf("%d\n",b);
Add(1,2);

注意:
在使用第三种方法后,相当于破坏了命名空间的所有围墙,将空间内所有成员暴露出来,此时成员就会出现与全局域中的成员同名的风险; 所以该方法,不建议在大型项目中使用,在平时练习时可以使用;第二种方法会破坏你所指定的成员的围墙,所指定的成员就会有与全局域成员同名的风险

头文件与std

我们在写C++时,首先打下的代码常常会是下面这两句:

#include<iostream>
using namespace std;

早期标准库将所有功能全部放在全局域中实现,其头文件也是以 .h 结尾;在后来为了将C++的库与C的区分开来,也为了防止命名冲突,C++将库的功能实现全部用命名空间包装起来,这个命名空间便是std,也规定了C++的头文件都不带.h结尾(早期编译器还是支持.h结尾的);

命名空间的本质

在这里先提出一个问题:在命名空间中的成员是局部变量,还是全局变量?
这里需要先搞明白一个点:局部变量是存在栈区的,什么情况下才会建立栈帧呢?只有在函数调用时才会建立栈帧;也就是说局部变量只会存在函数中;
那么命名空间是函数吗?很明显不是!命名空间本质只是将空间域中的成员与全局域中的数据隔离开来,使其成员不会与全局域中的成员重名,其成员本质仍是全局变量,只是访问时需要使用域作用限定符;

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

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

相关文章

基于node.js和Vue的音乐管理系统 /音乐网站的设计与实现

摘 要 本论文主要论述了如何使用node.js语言开发一个音乐管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述音乐管理系统的当前背景以及系统开发的目的&…

一、HTMLCSS

HTML 1. 目标 掌握HTML的简介和入门 掌握文本相关标签的使用 掌握超链接标签的使用 掌握div和span标签的使用 掌握图片标签的使用 掌握表格标签的使用 掌握表单标签的使用 2. 内容 2.1 HTML概念 HTML是Hyper Text Markup Language的缩写。意思是『超文本标记语言』。…

2019 WWW | HAN:Heterogeneous Graph Attention Network

2019 WWW | HAN:Heterogeneous Graph Attention Network Paper: https://arxiv.org/pdf/1903.07293.pdf Code: https://github.com/Jhy1993/HAN 2019 WWW | HAN:异构图注意网络 这篇文章在图神经网络中将注意力机制从同质图扩展到节点和边有不同类型的异质图。文章提出了一种…

什么东西可以替代触屏笔?Ipad触屏笔推荐品牌

要给ipad配一款电容笔&#xff0c;你会发现原来的苹果电容笔的要花费的资金远远超出了你的预算。平替电容笔&#xff0c;正最佳的选择。可以想像一下&#xff0c;一款原装的电容电容笔&#xff0c;可以购买四款平替电容笔&#xff0c;而一些电容笔在性能上甚至可以和苹果的电容…

Pr:自动匹配到序列

使用“自动匹配序列”命令可以快速组合粗剪或将剪辑添加到现有序列中&#xff0c;同时还可应用默认的视频和音频过渡。先在时间轴面板上定位好播放指示器位置&#xff0c;再在项目面板上选择要添加的剪辑。Pr菜单&#xff1a;剪辑/自动匹配序列Automate to Sequence或者&#x…

Qt moc: Too many input files specified

1.现象描述 在qt开发过程中&#xff0c;出现了如如下错误提示 qt moc: Too many input files specified 2.解决办法 查找网上的解决办法&#xff0c;如下这种可以解决&#xff1a; 1.使用moc将h文件手动生成moc文件&#xff1a; 如下所示&#xff1a; moc “F:\work\src\te…

微服务 | Nacos安装指南

CSDN话题挑战赛第2期 参赛话题&#xff1a;Java技术分享 前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;&#x…

【Java】ArrayList底层源码分析

ArrayList底层源码分析 **先上结论&#xff1a;**ArrayList如果传入的参数为空&#xff0c;那么会在第一次添加的时候初始化容量为10&#xff0c;添加满后会按1.5倍扩容。如果传入的参数为8&#xff0c;则初始化容量大小为8&#xff0c;添加满后再次扩容一样会按1.5倍扩容。Ar…

基于html+node的文化资讯网站设计

1 引言 4 1.1 课题背景 4 1.2课题意义 4 2相关技术简介 6 2.1 html技术 6 2.2 css技术 6 2.3 JavaScript 6 2.4 JQuery 6 2.5 Vue 7 2.6 MySQL技术 7 2.7 node.js技术 7 3需求分析 8 3.1 系统功能 8 3.2 系统开发环境 8 3.3功能性需求分析 8 3.3.1用户系统 8 3.3.2 文章系统 8 …

【leetcode】【2022/9/16】850. 矩形面积 II

问题描述&#xff1a; 我们给出了一个&#xff08;轴对齐的&#xff09;二维矩形列表 rectangles。 对于 rectangle[i] [x1, y1, x2, y2]&#xff0c;其中 (x1&#xff0c;y1) 是矩形 i 左下角的坐标&#xff0c;(xi1, yi1) 是该矩形左下角的坐标&#xff0c; (xi2, yi2) 是该…

C语言函数递归调用

1、函数递归调用的定义 递归函数定义&#xff1a;一个函数在 自己的函数体内 调用自己&#xff1b;执行递归函数将反复调用其自身&#xff0c;每调用一次就有一个新层 #include<stdio.h> // 函数声明 void diguifunc(); int main() //主函数 {diguifunc(); //运行后…

常用的软件架构

MVC 架构 MVP 架构 MVVM 架构 网上的一些常用架构解释图:MVC架构MVP架构

Haproxy 透传IP配置方法及测试

Haproxy 透传IP配置方法1. 环境准备2. 测试准备2.1 启动Haproxy容器方法2.1.1 拉取官方haproxy镜像2.1.2 删除旧的容器2.1.3 编写haproxy配置2.1.4 运行配置检查2.1.5 启动容器2.1.6 更改配置2.2 Golang Server编写2.2.1 TCP Server2.2.2 HTTP Server2.3 客户端测试2.3.1 设置网…

关于VC++运行库报错

Microsoft Visual C&#xff08;简称Visual C、MSVC、VC或VC&#xff09;是微软公司的C开发工具&#xff0c;具有一体化开发环境&#xff0c;可提供编辑 C语言&#xff0c;C以及C/CLI等程式语言。 VC集成了便利的调试工具&#xff0c;特别是整合了微软Windows窗口操作系统应用程…

家用网络常识

目前家庭使用的网速一般 运营商 销售的宽带,会说 50M 100M 200M 300M 这个 100M 指的就是 100M bit/s,而我们都知道 8bit相当于一个字节,也就是1B,所以换算成字节,其实是 12.5M B/s,也就是12.5M,12.5兆换算关系 1 KB = 1024 B 1 MB = 1024 KB 1 GB = 1024 MB 1 TB = 102…

联邦学习开源框架方案选型

无知者&#xff1a;【联邦学习开源框架】FedLab - 加速FL算法验证 联邦学习开源框架FedLab相关 FATE 单位&#xff1a;微众银行 github: https://github.com/FederatedAI/FATE star&#xff1a;3.2k docs&#xff1a;https://github.com/FederatedAI/FATE/blob/master/doc…

电力系统中新型预测双二元变量机组组合问题(Matlab代码实现)

目录 1 概述 2 Matlab代码实现 3 参考文献 1 概述 高效求解大规模 SCUC 问题的关键在于削减其规模。文献[1]表明&#xff0c;安全约束机组组合问题中 大量的故障态安全约束是冗余且无效的&#xff0c;不会对SCUC 问题的最优解产生影响。因此&#xff0c;可以通过辨 识、删除…

为什么ArrayList的subList结果不能转换为ArrayList????

subList是List接口中的一个方法,该方法主要返回一个集合中的一段子集,可以理解为截取一个集合中的部分元素,它的返回值也是一个List。 让我们初始化一个例子:import java.util.ArrayList; import java.util.List;public class SubList_demo {public static void main(Strin…

OPTEE:CA-TA会话的创建(二)

前言 在上一篇我们知道TA是什么&#xff0c;以及为什么需要加载TA。这里来写写加载TA后&#xff0c;怎么CA和TA&#xff0c;TA和TA怎么建立会话&#xff0c;实现我们的功能的。 参考内容全部来自《手机安全和可信应用开发指南》&#xff0c;少有OPTEE书籍&#xff0c;感恩前辈…

牛客网-SQL专项训练15

①MySQL是一种(关系型)数据库管理系统。 关系型数据库的代表包括Oracle, Sql Server, MySQL。 ②小李在创建完一张数据表后,发现少创建了一列,此时需要修改表结构,应该用哪个语句进行操作?C 解析: 题目中说了需要修改表的结构, 故需要使用alter table 添加列: ALTER T…