【C++掌中宝】深入解析C++命名空间:有效管理代码的利器

在这里插入图片描述

文章目录

  • 前言
  • 1. namespace 的价值
  • 2. namespace 的定义
  • 3. 命名空间的本质
  • 4. 嵌套的命名空间
  • 5. 命名空间的使用
  • 6. using 指令
  • 7. 补充
  • 结语

前言

假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。

同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。

我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名

在这里插入图片描述

1. namespace 的价值

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

c语言项目类似下面程序这样的命名冲突是普遍存在的问题,C++引入了命名空间这个概念,就是专门用于解决这种问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”printf("%d\n", rand);return 0;
}

2. namespace 的定义

命名空间的定义使用关键字 namespace,后跟命名空间的名称,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。如下所示:

namespace namespace_name {// 代码声明
}

为了调用带有命名空间的函数或变量,需要在前面加上命名空间的名称,如下所示:

name::code;  // code 可以是变量或函数

这里面的::作用域限定符

让我们来看看命名空间如何为变量或函数等实体定义范围:

#include <iostream>
using namespace std;// 第一个命名空间
namespace first_space{void func(){cout << "Inside first_space" << endl;}
}
// 第二个命名空间
namespace second_space{void func(){cout << "Inside second_space" << endl;}
}
int main ()
{// 调用第一个命名空间中的函数first_space::func();// 调用第二个命名空间中的函数second_space::func(); return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Inside first_space
Inside second_space

3. 命名空间的本质

  • namespace本质是定义出一个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不在冲突了。
#include <stdio.h>
#include <stdlib.h>
// 1. 一般的命名空间定义
// xhh是命名空间的名字,一般开发中是用项目名字做命名空间名。
namespace xhh
{// 命名空间中可以定义变量/函数/类型int rand = 10;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}
int main()
{// 这⾥默认是访问的是全局的rand函数指针printf("%p\n", rand);// 这⾥指定xhh命名空间中的randprintf("%d\n", xhh::rand);return 0;
}

C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。

4. 嵌套的命名空间

namespace 只能定义在全局,当然还可以嵌套定义,示例如下。

//2. 命名空间可以嵌套
namespace bit
{namespace pig{int rand = 1;int Add(int left, int right){return left + right;}}namespace bird{int rand = 2;int Add(int left, int right){return (left + right) * 10;}}
}
int main()
{printf("%d\n", bit::pig::rand);printf("%d\n", bit::bird::rand);printf("%d\n", bit::pig::Add(1, 2));printf("%d\n", bit::bird::Add(1, 2));return 0;
}

5. 命名空间的使用

编译查找一个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以下面程序会编译报错。

#include<stdio.h>
namespace N
{int a = 0;int b = 1;
}
int main()
{// 编译报错:error C2065: “a”: 未声明的标识符printf("%d\n", a);return 0;
}

所以声明了命名空间之后,如果在命名空间外部访问命名空间内部的成员,需要在成员名前面加上 命名空间::,示例如下。

// 指定命名空间访问
int main()
{printf("%d\n", N::a);return 0;
}

6. using 指令

有没有什么比较方便的方法能让我们直接通过成员名访问命名空间内的成员呢?答案是肯定的。我们可以使用 using 指令。

using 指令有如下两种形式:

  1. using 命名空间::成员名;

这条指令可以让我们省略某个成员名前的命名空间,直接通过成员名访问成员,相当于将这个成员导入了当前的作用域。

// using将命名空间中某个成员展开
using N::b;
int main()
{printf("%d\n", N::a);printf("%d\n", b);return 0;
}
  1. using namespace 命名空间;

这条指令可以直接通过成员名访问命名空间中的任何成员,相当于将这个命名空间的所有成员导入了当前的作用域。

// 展开命名空间中全部成员
using namespce N;
int main()
{printf("%d\n", a);printf("%d\n", b);return 0;
}

因此,如果执行了 using namespace N;,就会将 N 中的所有名字都会引入到全局命名空间当中。

📌注意

  • 指定命名空间访问。项目中推荐这种方式。

  • using将命名空间中某个成员展开。项目中经常访问的不存在冲突的成员推荐这种方式。

  • 展开命名空间中全部成员,由于这种方式会将此命名空间中的所有名字引入,因此如果声明了与其中重名的变量或函数,就可能会因为命名冲突而导致编译错误。所以说项目中不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。

7. 补充

  • 项目工程中多文件中定义的同名namespace会认为是一个namespace,不会冲突。

  • C++标准库都放在一个叫std(standard)的命名空间中。

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Modular Elven Archer 幻想精灵女弓箭手游戏角色模型

可爱的精灵射手的3D模型。用额外的骨骼固定到人形。完全模块化,包括一个没有衣服的身体。包含苹果混合形状。 下载:​​Unity资源商店链接资源下载链接 效果图:

Java-数据结构-优先级队列(堆)-(二) (゚▽゚*)

文本目录&#xff1a; ❄️一、PriorityQueue的常用接口&#xff1a; ➷ 1、PriorityQueue的特性&#xff1a; ➷ 2、使用PriorityQueue的注意&#xff1a; ➷ 3、PriorityQueue的构造&#xff1a; ☞ 1、无参数的构造方法&#xff1a; ☞ 2、有参数的构造方法&#xff1a; …

Error when custom data is added to Azure OpenAI Service Deployment

题意&#xff1a;在向 Azure OpenAI 服务部署添加自定义数据时出现错误。 问题背景&#xff1a; I receive the following error when adding my custom data which is a .txt file (it doesnt matter whether I add it via Azure Cognitive Search, Azure Blob Storage, or F…

uniApp微信小程序扫描普通二维码跳转到小程序指定页面操作方法

这篇文章主要给大家介绍了关于微信小程序扫描普通二维码跳转到小程序指定页面操作的相关资料,需要的朋友可以参考下 1、首先我们需要在微信公众平台的开发管理——>开发设置&#xff0c;找到&#xff08;扫普通链接二维码打开小程序&#xff09;&#xff0c;点击添加,根据提…

C++ 9.20

练习&#xff1a;定义一个矩形类&#xff08;Rectangle&#xff09;&#xff0c;包含私有成员宽度&#xff08;width&#xff09;、高度&#xff08;height&#xff09; 包含公共成员函数&#xff1a; 初始化矩形&#xff08;init&#xff09; 设置宽度&#xff08;set_w&am…

给儿童掏耳朵用哪个好?儿童耳勺最建议买的五个牌子

儿童的耳朵清洁是家长最烦恼的事情之一&#xff0c;近年来传统耳勺出现的意外新闻颇多&#xff0c;棉签等工具的表面粗糙&#xff0c;稍不注意就会刮伤儿童脆弱的耳道肌肤&#xff0c;那么除了这些以外&#xff0c;给儿童掏耳朵用哪个好&#xff1f; 小编建议家长都入一个可视挖…

唤醒数据中台潜力,加速数据飞轮转动:数据驱动秘籍

在这个数据爆炸的时代&#xff0c;企业的数据资产正变得越来越重要。然而&#xff0c;收集和存储数据只是数据驱动旅程的第一步。如何唤醒这些沉睡的数据&#xff0c;真正让它们为业务服务&#xff1f; 这才是企业成功的关键。 数据中台曾被视为整合企业内外数据资源的利器&am…

javascript 3 个有序点的方向(Orientation of 3 ordered points)

给定三个点 p1、p2 和 p3&#xff0c;任务是确定这三个点的方向。 平面中有序三重点的方向可以是 逆时针 顺时针 共线 下图显示了 (a,b,c) 的不同可能方向 如果 (p1, p2, p3) 的方向共线&#xff0c;则 (p3, p2, p1) 的方向也共线。 如果 (p1, p2, p3) 的方向是顺时针&a…

Python GUI 编程:tkinter 初学者入门指南——窗口

目录&#xff1a; 创建窗口更改窗口标题更改窗口大小和位置窗口在屏幕上居中窗口设置的其他属性 Tkinter 是在 Python 中开发 GUI&#xff08;图形用户界面&#xff09;最常用的库。在本指南中&#xff0c;我们将引导您了解 Tkinter 的基本知识&#xff0c;学习如何使用 Tkinte…

Vue3:自定义事件实现组件通信

目录 一.性质 1.双向通信 2.灵活性 3.传参能力 4.声明机制 5.事件验证 6.修饰符支持 7.响应式更新 8.解耦组件 9.易于测试 10.性能优化 二.使用 1.父组件 2.子组件 三.代码 1.父组件代码 2.子组件代码 四.效果 在Vue3中&#xff0c;自定义事件是实现组件间通…

NLP(二)-文本表示

One-hot One-hot&#xff08;独热&#xff09;编码是一种最简单的文本表示方式。如果有一个大小为V的词表&#xff0c;对于第i个词$w_i$&#xff0c;可以用一个长度为V的向量来表示&#xff0c;其中第i个元素为1&#xff0c;其它为0.例如&#xff1a; 减肥&#xff1a;[1, 0,…

C++11之统一的列表初始化

一.{}初始化 在c98中&#xff0c;标准允许使用{}对数组或结构体元素进行统一的列表初始值设定&#xff1a; struct mess {int _x;string _str; }; int main() {//注意&#xff0c;使用new的一定是指针int* arr new int[4] {1, 2, 3, 4};//数组初始化int arr[] { 1,3,5,6 };…

深度学习激活函数

激活函数是神经网络模型重要的组成部分&#xff0c;本文作者Sukanya Bag从激活函数的数学原理出发&#xff0c;详解了十种激活函数的优缺点。 激活函数&#xff08;Activation Function&#xff09;是一种添加到人工神经网络中的函数&#xff0c;旨在帮助网络学习数据中的复杂模…

linux之nacos安装

1:下载nacos安装包 方式一、进入官网下载压缩包 官网地址 找到nacos-server-2.0.1.tar.gz 点击进行下载&#xff0c;下载完成后上传到服务器中。 方式二、使用wget命令下载 也有两种方式&#xff1a;第一种下载速度较慢 wget https://github.com/alibaba/nacos/releases/downl…

圆柱包围框-Bounding Cylinder-原理-代码实现

定义&#xff1a;使用一个圆柱体包围点云的所有点&#xff0c;通常用于长柱状物体。 优点&#xff1a;适合于柱状或长条形的点云。 缺点&#xff1a;计算较为复杂&#xff0c;尤其是确定圆柱体的轴线方向和半径。 找到圆柱尽量满足下面条件 找到能够完全包围3D物体的最小圆柱…

户外无线麦克风哪个牌子好,降噪麦克风哪个牌子好,领夹麦推荐

对于热爱记录与户外直播的自媒体人来说&#xff0c;一款高性能的无线领夹麦克风决定了音频的质量。市场上虽有品牌如大疆、罗德、西圣等凭借技术创新引领潮流&#xff0c;但同时也存在一些产品&#xff0c;因设计缺陷在运动时声音捕捉不稳定。作为运动爱好者与音频设备测评师&a…

网络资源模板--Android Studio 图书借阅App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--图书借阅App 二、项目测试环境 三、项目详情 首页 这段代码是一个 Android 应用的 MainActivity 类&#xff0c;功能简要总结如下&#xff1a; 1. **界面设置**&#xf…

数据结构不再难懂:带你轻松搞定图

数据结构入门学习&#xff08;全是干货&#xff09;——图 1 图 1.1 什么是图 图是一种用于表示多对多关系的数学模型。它由一组顶点和一组边构成&#xff0c;用于描述事物之间的复杂关联。 顶点&#xff1a;通常用 V (Vertex) 表示&#xff0c;代表事物或对象。边&#xf…

2024华为杯研赛E题保姆级教程思路分析

E题题目&#xff1a;高速公路应急车道紧急启用模型 今年的E题设计到图像/视频处理&#xff0c;实际上&#xff0c;E题的难度相对来说较低&#xff0c;大家不用畏惧视频的处理&#xff0c;被这个吓到。实际上&#xff0c;这个不难&#xff0c;解决了视频的处理问题&#xff0c;…

华为---代理ARP工作过程示例分析

目录 1. 示例场景 2. 基本配置 3. 配置代码 4. 测试验证 5. 抓包分析 5.1 在代理ARP环境下PC1和PC2通信分析 5.2 取消代理ARP环境下PC1和PC2通信分析 【1】取消R1路由器GE 0/0/1端口ARP代理 【2】取消R2路由器GE 0/0/1端口ARP代理 1. 示例场景 如上图所示&#xff0c;…