【C++入门】命名空间的定义与使用

news2024/9/24 7:23:25

目  录

  • 1 命名空间
    • 1.1 命名空间定义
    • 1.2 命名空间使用


1 命名空间

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

C语言中命名冲突示例:

命名测试

如上图所示:在左部分代码中,我们没有包含头文件stdlib.h,运行后正常输出了全局变量 rand 的值;而在右部分代码中,我们包含了头文件stdlib.h,此时再运行程序,报错说明 rand 发生了重定义,之前的 rand 是被定义为一个函数。显然,这是因为 rand 是stdlib.h中声明的库函数,当我们在包含了stdlib.h头文件的同时又声明了与函数同名的 rand 全局变量时就会发生命名冲突,进而导致程序无法正常运行。

命名冲突通常发生于以下几种情况:

  • 我们自己定义的变量、函数、类与库里的名字发生命名冲突。
  • 在项目组中,多个人之间定义的名字发生冲突。可能单个人运行自己的代码时是正常的,可当将多人的代码进行合并后,运行就发生了命名冲突。

命名冲突问题是C语言的一个缺陷,在C语言中没有办法很好解决这个问题。因此,C++在C语言的基础上增加了命名空间的概念以解决这个问题。

在认识命名空间之前,我们先了解一个相对于C语言C++中新增的操作符:域操作符(域作用符) :: (双冒号),当全局变量与某个函数中的局部变量重名时,即可用 :: 来区分,表示要使用哪个域中的同名变量。如下示例:当函数中定义有与全局变量同名的变量时,默认情况下,调用函数会优先使用函数中的同名局部变量;如果想要在该函数中使用同名全局变量,则需要用域作用符 :: 来修饰变量(格式如下图代码中所示),当域作用符左边无其它名称时(如命名空间),则默认表示全局域,使用全局变量。

域作用符使用示例


1.1 命名空间定义

定义一个命名空间实际上就是定义一个域,命名空间中的所有内容都局限于该空间中。命名空间的定义只影响使用,不影响生命周期。定义命名空间需要使用 namespace 关键字。后跟空间名字,然后接一对 {} 即可, {} 中即为命名空间中的成员。

定义方式:

  • 正常命名空间定义
    namespace (域名或空间名)
    {
    {\kern 8pt} //命名空间中的成员:可以定义变量、函数、类。如下例:
    {\kern 8pt} int rand = 10; //全局变量
    {\kern 8pt} //函数
    {\kern 8pt} int Add(int num1, int num2)
    {\kern 8pt} {
    {\kern 16pt} retrun num1 + num2;
    {\kern 8pt} }
    {\kern 8pt} //结构体类型
    {\kern 8pt} struct Node
    {\kern 8pt} {
    {\kern 16pt} struct Node* next;
    {\kern 16pt} int val;
    {\kern 8pt} };
    }
  • 命名空间嵌套定义
    // test.cpp
    namespace N1
    {
    {\kern 8pt} int a;
    {\kern 8pt} int b;
    {\kern 8pt} int Add(int num1, int num2)
    {\kern 8pt} {
    {\kern 16pt} return num1 + num2;
    {\kern 8pt} }

    {\kern 8pt} namespace N2
    {\kern 8pt} {
    {\kern 16pt} int c;
    {\kern 16pt} int d;
    {\kern 16pt} int Sub(int num1, int num2)
    {\kern 16pt} {
    {\kern 20pt} return num1 - num2;
    {\kern 16pt} }
    {\kern 8pt} }
    }
  • 同一个工程中,允许存在多个相同名称的命名空间,编译器最后会将同名的命名空间合并为一个空间。(如第二点中的test.cpp中的 N1 空间与下面的test.h中的 N1 空间,假设test.cpp与test.h属于同一个工程,则最后者这两个同名空间将会被合并成一个空间)
    namespace N1
    {
    {\kern 8pt} int Mul(int num1, int num2)
    {\kern 8pt} {
    {\kern 16pt} return num1 * num2;
    {\kern 8pt} }
    }

1.2 命名空间使用

那命名空间中的成员该如何使用呢?如下图所示,我们定义一个命名空间 N1 时,当不加任何说明,直接使用命名空间中的成员时,程序发生编译报错:说明使用的该成员是未声明的标识符。

命名空间使用示例

事实上,当我们使用某个变量、类型等时,编译器会默认先在局部域查找,如果找不到再到全局域查找,如果全局也没有就将发生报错。默认情况下编译器不会到命名空间中进行查找,因此,如果我们想要使用某个命名空间中的成员时,应当对该成员所属空间进行说明,使得编译器能够到指定的域中找到它。

命名空间有以下三种使用方式:

  • 在标识符前加其所在命名空间名称及作用域限定符 ::

int main(){
{\kern 8pt} struct N1::Node node;
{\kern 8pt} printf(“%d\n”, N1::a);
{\kern 8pt} return 0;
}
需要注意的是:空间名及域作用符须直接加在标识符前,使用如 N1::struct Node node; 的写法是错误的;如果使用的成员在嵌套定义的命名空间中,则应以如 N::N1::a 嵌套的方式进行说明(其中N1空间嵌套在N空间中,a是N1空间中的成员)。

  • 使用关键字 using 将命名空间中的某个成员引入(相当于将命名空间中部分成员展开到全局域中)

using N1::b;
int main(){
{\kern 8pt} printf(“%d\n”, N1::a);//没有展开的成员仍需使用空间名及域作用符进行说明
{\kern 8pt} printf(“%d\n”, b);
{\kern 8pt} return 0;
}

  • 使用 using namespace 将命名空间名称引入(相当于将命名空间中的成员全部展开到全局域中,或者说告知编译器将会使用到该空间中的成员,使得编译器会到该空间中进行查找)

using namespace N1;
int main(){
{\kern 8pt} printf(“%d\n”, a);
{\kern 8pt} printf(“%d\n”, b);
{\kern 8pt} Add(10, 20);
{\kern 8pt} return 0;
}


在C++的代码中,我们常看到这样一句:using namespace std ,这是由于为了避免我们自己定义的某个标识符与标准库中的标识符重名,C++中标准库中的东西都被放到了名为 std 的命名空间中,如果我们仅是包含了相关头文件而没有将标准库对应空间中的内容展开,那依旧无法使用标准库中的成员,这句代码则表示将标准库中的东西全部展开到全局域中。

值得注意的是: 早期标准库将所有功能在全局域中实现,声明在 .h 后缀的头文件中,使用时只需包含对应的头文件即可,后来将其实现在 std 命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带 .h ;旧编译器还支持 <iostream.h> 格式,后续编译器已不支持,因此推荐使用 < iostream >+std 的方式。


std命名空间使用惯例:

  • 在日常练习中,建议直接使用 using namespace std 进行全局展开即可,这样比较方便使用。
  • 使用 using namespace std 进行全局展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型、对象、函数,就会存在命名冲突问题,该问题在日常练习中很少出现,但在实际项目开发中代码较多、规模较大,就很容易出现这个问题。所以建议在实际项目开发中使用如 std::cout 这样使用时指定命名空间或 using std::cout 展开常用的库对象、类型等的方式。

以上是我对C++中命名空间相关的一些学习记录总结,如有错误,希望大家帮忙指正,也欢迎大家给予建议和讨论,谢谢!

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

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

相关文章

经典动态规划OJ题目:接雨水or接青豆(多种方法,附详详细思维过程、解析及源码)

作者&#xff1a;非妃是公主 专栏&#xff1a;《算法》《刷题笔记》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 《算法》专栏系列文章 算法设计与分析复习01&#xff1a;主方法求递归算法时间复杂度 算法设计与分析…

MySQL批量插入4种方案(对比速度起飞)

一、前言二、准备工作1、Maven项目中pom.xml文件引入的相关依赖如下2、application.yml配置属性文件内容&#xff08;重点&#xff1a;开启批处理模式&#xff09;3、Entity实体类&#xff08;测试&#xff09;4、数据库student表结构&#xff08;注意&#xff1a;无索引&#…

4.2 避免缩进错误

4.1.3 在for循环结束后执行一些操作for循环结束后再怎么做呢?通常,你需要提供总结性输出或接着执行程序必须完成的其他任务。在for循环后面&#xff0c;没有缩进的代码都只执行一次&#xff0c;而不会重复执行。下面来打印一条向全体魔术师致谢的消息&#xff0c;感谢他们的精…

爬虫实例(一) —— 5行 Python 代码爬取

大家好&#xff0c;我是 Enovo飞鱼&#xff0c;今天分享一个爬虫小案例&#xff0c;小白或者爬虫入门的小伙伴推荐阅读&#xff0c;加油&#x1f4aa;。 目录 前言 基本环境配置 爬取目标网站 爬取内容 实现代码 后面我会继续更新爬虫实例&#xff0c;与大家共同学习&am…

ubuntu设置双网卡以及多网段

前提设备有两个网卡&#xff0c;分别作为内网和外网,比如两个网卡eth0和eth1,eth0作为外网&#xff0c;eth1作为内网&#xff0c;每个人的网卡名称可能不一样&#xff0c;网卡名称可以自行查看&#xff0c;使用ifconfig命令&#xff1a;ifconfig区分内网和外网的ip外网网卡&…

如何使用 Apache IoTDB 中的 UDF

本篇作者&#xff1a;IoTDB 社区 -- 廖兰宇本文将概述用户使用 UDF 的大致流程&#xff0c;UDF 的详细使用说明请参考官网用户手册&#xff1a;https://iotdb.apache.org/zh/UserGuide/Master/Operators-Functions/User-Defined-Function.html1编写 UDFIoTDB 为用户提供编写 UD…

opensuse15.4安装android-studio-2021.1.1.23_未完成

opensuse15.4安装android_studio再运行微信apk_未完成 未完成的原因是&#xff1a;本人台式机的物理内存为4G&#xff0c;官方要求是16G android studio与android sdkj是两个完全不同的两样东西。 Android studio是一个IDE&#xff08;可视化开发工具&#xff09;跟eclipse一…

SAP 新准则IFRS 17:重新思考和革新保险会计的机会

您准备好迎接 IFRS 17 了吗&#xff1f;财务报告准则过去曾多次更改&#xff0c;但这次没有。这一变化将为准备迎接新准则的保险公司带来广泛的机遇。许多公司都有应对这些要求的战术计划。但最大的成功将由制定包括 IFRS 17 在内的更广泛报告战略的公司实现。他们不会做出回应…

redis-哈希槽一致hash算法

1、一致性hash算法&#xff1f; 以分布式缓存为例&#xff0c;假设现在有3台缓存服务器(S0&#xff0c;S1&#xff0c;S2)&#xff0c;要将一些图片尽可能平均地分配到不同的服务器上&#xff0c;hash算法的做法是&#xff1a; (1) 以图片的名称作为key&#xff0c;然后对其做…

【Unity3D插件】UniRx(基于Unity的响应式编程框架)插件教程

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客QQ群&#xff1a;1040082875 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、介绍UniRx插件 UniRx是一种基于Unity3D的…

九龙证券|石墨烯电池和锂离子电池哪个好

电池技术是电动汽车大力推广和开展的最大门槛&#xff0c;而电池工业正处于铅酸电池和传统锂电池开展均遇瓶颈的阶段&#xff0c;石墨烯储能设备的研制成功后&#xff0c;若能批量生产&#xff0c;则将为电池工业乃至电动车工业带来新的改造。那么石墨烯电池和锂离子电池哪个更…

VUE VS React 对比

VUE VS React 对比 这是面试中经常考察的一个问题&#xff0c;简单整理一下。我主要写 react &#xff0c;所以 react 的特点阐述的多一点。 语法格式 vue 是单独的文件格式&#xff0c;一个文件包括了 js css HTML 全部 React 通常是 jsx 格式&#xff0c;JS 和 HTML 写在…

shiro相关源码解析

1. 认证过程相关源码解析 前后文可接查看 shiro的登陆都是通过subject.login()方法实现&#xff0c;接下来我们就进入login方法查看实现过程&#xff1a; 1.1 进入DelegatingSubject类的login方法&#xff1a; 此类实现了Subject接口&#xff1a; public void login(Authen…

基于ssm的高校二手物品交易网 java idea mysql

本文论述了民办高校二手物品交易网的设计和实现&#xff0c;该网站从实际运用的角度出发&#xff0c;运用了计算机网站设计、数据库等相关知识&#xff0c;网络和Mysql数据库设计来实现的&#xff0c;网站主要包括用户注册、用户登录、浏览商品、搜索商品、查看商品并进行购买&…

bilibili全链路压测改造之全链自动化测试实践

01 、背景与意义 B站直播营收送礼业务有着高写、在跨晚和S赛等大型活动下流量陡增、数据实时性要求高等特性&#xff0c;传统压测对于写场景为了避免影响线上数据做了各种屏蔽和黑名单处理&#xff0c;有着无法逼近线上真实情况的问题&#xff0c;因此业务对全链路压测有着较大…

拿下阿里自动化测试岗23k*14薪offer的全程面试记录解析以及总结,一面二面三面,项目,功能,自动化,性能测试,面试题问答

一、自我介绍 面试官您好&#xff01;我叫xx&#xff0c;来自深圳&#xff0c;毕业之后一直从事于软件测试的工作&#xff0c;有做过保险、金融、电商等项目&#xff1b;有做过做功能测试、接口测试&#xff0c;自动化测试&#xff0c;在工作中积极主动、可以独立的完成测试工…

shiro(一):shiro基本概念及基本使用(认证、授权)

1. 权限的管理 1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。 权限管理包括用…

算法刷题打卡第76天:判断矩阵是否是一个 X 矩阵

判断矩阵是否是一个 X 矩阵 难度&#xff1a;简单 如果一个正方形矩阵满足下述 全部 条件&#xff0c;则称之为一个 X 矩阵 &#xff1a; 矩阵对角线上的所有元素都 不是 0 矩阵中所有其他元素都是 0 给你一个大小为 n x n 的二维整数数组 grid &#xff0c;表示一个正方形矩…

CV——day72:从零开始学YOLO——YOLO-v3(可以在我的资源里下载完整的v1到v3的笔记啦!)

YOLO-v36. YOLO-v36.1 YOLO-v3 改进综述6.2 多scale方法改进与特征融合6.3 经典变换方法对比分析6.4 残差连接方法解读6.5 整体网络模型架构分析6.6 先验框设计改进6.7 softmax层改进6. YOLO-v3 **tips&#xff1a;**作者本人因为美军广泛运用于军事领域&#xff0c;所以决定不…

基于php电影点播平台/电影网站

摘要网络技术给生活带来了十分的便利。所以把电影点播平台与现在网络相结合。在点播平台发展的整个过程中&#xff0c;电影信息管理担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类电影信息管理程序也在不断改进。本课题所设计的电影点播平台&#xff0c;使…