2023-09-07 C++命名空间的一些陷阱


老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>


C++命名空间的一些陷阱

  • 前言
  • 一、命名空间是什么?(InsCode AI 创作助手)
  • 二、命名空间全局污染
  • 总结


前言

最近看到个问题, 就是在命名空间中声明一个变量 ( int rand = 0 ), 用using namespace将这个命名空间引入 ( 污染 ) 进全局空间, 当函数调用此变量时发生错误.

这是命名空间全局污染典型案例, 我们进行一些剖析


一、命名空间是什么?(InsCode AI 创作助手)

C++ 命名空间(namespace)是一种将全局作用域分割为若干个小的作用域的机制。

它可以解决命名冲突(name clash)的问题,使不同作用域下的同名标识符互不干扰。

命名空间的使用方法如下:

1.定义命名空间:可以在全局空间下定义命名空间,也可以在已有的命名空间内定义子命名空间,例如:

namespace math
{int add(int a, int b){return a + b;}namespace geometry{double circle_area(double r){return 3.14159 * r * r;}} // namespace geometry
} // namespace math

2.使用命名空间:可以用 using namespaceusing 关键字引入一个或多个命名空间,也可以使用作用域限定符访问命名空间中的标识符。

using namespace math; // 引入 math 命名空间using math::geometry::circle_area; // 仅引入 math::geometry::circle_area 标识符int main()
{int sum = math::add(1, 2); // 使用作用域限定符访问 math 命名空间中的函数double area = circle_area(10.0); // 直接使用 circle_area 标识符(已引入)return 0;
}

二、命名空间全局污染

命名空间是一种防止变量和函数因名称重复, 导致程序失败的机制。

全局污染是指太多的变量和函数被定义在全局命名空间中,容易产生命名冲突和互相干扰,从而导致程序出现错误。

通过使用命名空间,可以将变量和函数封装到特定的命名空间中,以避免与其他变量和函数冲突。

这提高了代码的可维护性和可读性,并使代码更易于理解和修改。

但是, 有一种不良的编程习惯, 就是将命名空间引入全局, 导致全局污染的发生.

以下是一个示例, 根据关于c++的命名空间的一个问题的问答代码, 做的修改.

#include <iostream>namespace hk
{int rand = 0;
}using namespace hk;auto main() -> int
{auto a = rand;
}

代码中, hk作为一个命名空间, 被引入到全局, 然后我们惊讶的发现, 程序中的 rand 发生了冲突, 编译器无法识别, rand究竟是一个int对象还是一个函数指针.

仔细剖析, 发现, rand本身是一个库函数, 当 hk 污染进全局, 作为int对象的 rand 和 函数名 rand 冲突了.

只是我们没有引入过与rand函数相关的头文件, 这个rand又是哪里来的?

这就是C++的要命之处, 头文件的相互引用.

我们只是引入<iostream>, 而它又引用其他头文件, 其他头文件不知引用了多少次之后, 引用了 <stdlib.h> 头文件, 是的, 你无法知道你的实现代码中究竟引用了什么.

这也是为什么, C++的前辈告诉我们, 永远不要使用using namespace将命名空间引入全局的原因, 这与命名空间的初衷背道而驰, 它是用来解决命名冲突问题的, 不是引入命名冲突问题的.

所以, 在偷懒的时候, 一定要知道偷懒可能产生的代价.

为了解决上述问题, 代码不得不改为:

auto main() -> int
{auto a = hk::rand;auto b = ::rand;
}

总结

有时候, 前人总结的经验不一定立刻起到作用, 比如, 绝对不要人为引入全局空间污染,

但当你违背以上警告, 却没有产生问题, 还貌似提高了打字效率,

殊不知, 各种莫名奇妙的bug就在路上等着, 你可能害了整个团队, 让一个下游程序员莫名奇妙的追踪数百乃至数万个编译报错, 蹂躏并撕扯下他本就所剩无几的头发.


老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>


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

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

相关文章

方向介绍:基于深度学习的轨迹预测

方向介绍&#xff1a;基于深度学习的轨迹预测 文章目录 方向介绍&#xff1a;基于深度学习的轨迹预测问题定义典型方法挑战未来展望参考 基于深度学习的轨迹预测是一种利用神经网络模型来预测移动物体的未来位置和运动状态的技术。这种技术在许多领域都有重要的应用&#xff0c…

常见数据库介绍对比之SQL关系型数据库

1.关系型数据库介绍 关系型数据库是一种基于关系模型的数据库&#xff0c;它使用表格来组织和存储数据。下面是一些常见的关系型数据库&#xff1a; 1.1. MySQL MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛用于Web应用程序和企业级…

Nosql数据库服务之redis

Nosql数据库服务之redis 一图详解DB的分支产品 Nosql数据库介绍 是一种非关系型数据库服务&#xff0c;它能解决常规数据库的并发能力&#xff0c;比如传统的数据库的IO与性能的瓶颈&#xff0c;同样它是关系型数据库的一个补充&#xff0c;有着比较好的高效率与高性能。 专…

AlexNet 06

一、发展 1989年&#xff0c;Yann LeCun提出了一种用反向传导进行更新的卷积神经网络&#xff0c;称为LeNet。 1998年&#xff0c;Yann LeCun提出了一种用反向传导进行更新的卷积神经网络&#xff0c;称为LeNet-5 AlexNet&#xff0c;VGG&#xff0c;GoogleNet&#xff0c;R…

计算机网络常见端口号

端口号标识了一个主机上进行通信的不同的应用程序。比如网站服务器80端口一般都是开启的&#xff0c;等你来连接。 端口划分&#xff1a; &#xff08;1&#xff09;常用端口&#xff0c;公共端口&#xff08;保留给公共服务所使用&#xff09;&#xff0c;端口号为0-1023之间…

三色标记整理

在并发标记过程中&#xff0c;因为标记期间应用线程还在继续跑&#xff0c;多标漏标的情况有可能发生 把Gcroot可达性分析遍历分析对象过程中遇到的对象&#xff0c;按照知否访问过来标记三种颜色 黑色&#xff1a;表示这个对象已经被垃圾收集器访问过&#xff0c;且所有的引用…

小鹏汽车在滴滴上眺望远方

监制 | 何玺 排版 | 叶媛 小鹏汽车越来越有看头了。 前不久&#xff0c;小鹏汽车宣布与滴滴出行达成战略合作&#xff0c;将采用股票增发形式&#xff0c;收购滴滴旗下的智能电动汽车项目。 预计到2024年&#xff0c;小鹏汽车将依托这次收购的技术和资产&#xff0c;向市场推…

运维监控系统PIGOSS BSM 业务监控 大屏展现解析

“业务大屏”是 PIGOSS BSM&#xff08;IT运维监控工具&#xff09;的特色功能之一&#xff0c;旨在提供综合而直观的业务监控视图。该功能主要由三个组成部分构成&#xff1a;业务健康度雷达图、业务状态矩阵和多趋势对比图。 下面将对每个部分进行详细介绍&#xff1a; 业务健…

支持向量机

一、支持向量机 1. 基本概念 1&#xff09;什么是支持向量机 支持向量机&#xff08;Support Vector Machines&#xff09;是一种二分类模型&#xff0c;在机器学习、计算机视觉、数据挖掘中广泛应用&#xff0c;主要用于解决数据分类问题&#xff0c;它的目的是寻找一个超平…

CDN+GitHub搭建图床

前期搭建博客的时候&#xff0c;老是遇到图片无法加载、加载出错等等问题&#xff0c;很是烦恼。于是想搭建一个图床&#xff0c;进行个人博客图片的存储、显示使用。 ​ 利用GitHubjsDelivrPicGo搭建免费图床&#xff0c;CDN图床就是这么朴实无华&#xff0c;是基于免费CDN与免…

敏感信息防泄漏:透明加密与通信内容安全策略深度解析

随着信息技术的迅猛发展&#xff0c;计算机和网络已经成为了我们日常生活中不可或缺的工具&#xff0c;用于办公、通信和协作。尽管这些信息系统提高了工作效率&#xff0c;但也引发了一系列与信息安全相关的问题&#xff0c;例如如何有效地保护存储在这些系统中的关键数据&…

实训七:存储过程与触发器 - 存储过程、函数与触发器

存储过程、函数与触发器 第1关&#xff1a;创建存储过程任务描述相关知识存储过程的定义存储过程的创建和查询存储过程的查询和删除 编程要求测试说明参考代码 第2关&#xff1a;创建函数-count_credit任务描述相关知识自定义函数的定义自定义函数的创建 编程要求测试说明参考代…

【C++漂流记】函数的高级应用——函数默认参数、占位参数、重载

函数的高级应用&#xff0c;侧重介绍函数的默认参数、函数的占位参数、函数重载定义解释及使用。 文章目录 一、函数的默认参数二、函数的占位参数三、函数重载函数重载的注意事项 一、函数的默认参数 函数默认参数是指在函数声明时为参数提供一个默认值&#xff0c;这样在调…

算法通关村第十三关——溢出问题处理模板

前言 溢出问题是面试当中输出涉及到数字的一个需要特别注意的地方&#xff0c;典型的题目有三个&#xff1a;数字反转&#xff0c;将字符串转成数字和回文数。 1.整数反转 力扣7题&#xff0c;给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。…

ORACLE 11.2.0.4 RAC Cluster not starting cssd with Cannot get GPnP profile

最近&#xff0c;处理一次oracle 11.2.0.4 rac cluster由于cssd无法启动&#xff0c;导致集群一个节点的CRS集群无法正常启动的故障。原本&#xff0c;计划变更是从ASM剔除磁盘&#xff0c;解除存储到数据库服务器的映射&#xff1b;磁盘已经成功从ASM剔除&#xff0c;也已经成…

数据库误修改后的数据恢复

一不小心将数据库数据修改了&#xff0c;而且回滚无效&#xff0c;于是去尝试各种方法恢复数据 查询到修改时间点之前的数据 恢复数据 恢复数据库被修改数据的流程及代码&#xff0c;这里被修改的表是AUTH_USER,实际应用填写对应表名。 -- 通过时间恢复删除且已提交的数据-- 1…

uni-app rich-text组件富文本图片展示不全问题

背景&#xff1a;phpfastadmin富文本插件上传富文本内容到数据库&#xff0c;uni-app渲染富文本内容。这里后端不需要特殊处理。uni-app的rich-text组件展示图片跑板。直接贴代码。 <template><view><title-bar title"会员动态" back backcolor"…

解释区块链技术的应用场景和优势

概述 区块链技术是一种分布式数据库技术&#xff0c;用于存储和传输数字资产&#xff08;如加密货币&#xff09;的信息。它通过将交易记录分散保存到节点网络中的多个节点上&#xff0c;从而保证了数据的安全性和透明度。区块链技术的核心是基于密码学技术的算法&#xff0c;…

JDK1.8下载、安装和环境配置使用

JDK1.8下载、安装和配置 下载安装包解压文件配置测试安装 下载安装包 链接地址 https://pan.baidu.com/s/1RF7-ulq0_qAelpXskDxdvA 提取码 d1y0解压文件 jdk1.8.0_181 配置 右击我的电脑&#xff0c;选择属性 2.点击高级系统设置 在系统变量区里点击&#xff1a;新建…

Oralce集群管理-19C RAC 私有网络调整为BOND1

1 尝试在线添加私有网络的新接口 是否成功。 使用oifcfg命令在线添加新的网卡接口&#xff0c;在还没有配置bond1的条件下 也是可以添加成功的。 [gridorcldb1 ~]$ oifcfg getif eno3 192.168.224.0 global public ens3f0 10.2.0.0 global cluster_interconnect,asm eno…