详解:为什么尽量不要使用 using namespace std?

简介: C++辅导专栏

A:


需要保证的是尽量不要在头文件里 using 任何东西尤其是 namespace,要不然 include 进来的时候很容易莫名其妙产生命名冲突。


有条件的话,所有引入的符号都定义在自己的 namespace 里。任何情况下都不要 using namespace std 从理论上来说也是有道理的:因为系统库可能会升级,这样升级编译使用的 C++ 版本的时候有可能因为引入了新的符号跟自己代码里的命名冲突。


但一般来说,升级 C++ 版本最多几年也就做一次,冲突的可能性也并不大,而升级 C++ 版本本来也不一定能保证编译成功,为了这种特殊时候省一点时间让平时的编码和阅读都变费劲并没有什么道理。


B:

其实底线就一条:如果你的头文件(*.h、*.hpp)有被外部使用,则不要使用任何 using 语句引入其他命名空间或其他命名空间中的标识符。


因为这可能会给使用你的头文件的人添麻烦。更何况头文件之间都是相互套的,假如人人都在头文件里包含若干个命名空间,到了第 N 层以后突然出现了一个命名冲突,这得往前回溯多少层才能找到冲突啊。而这个冲突本来是可以避免的。


其实在源文件(*.cpp)里面怎么 using 都是没关系的,因为 cpp 里的代码不影响到他人。甚至如果你的头文件(*.h、*.hpp)只是自己用,那 using 也是没事的。但为了养成良好的习惯,很多人仍然建议不要随便 using,以防写顺手,届时在共享的头文件里也顺手 using 了,造成人祸。


C:


举一个简单的例子: 我们原来的代码一直没问题,但如果要使用 C++17 标准就报一个错,这个错影响还挺多的。具体原因是,C++17 添加了一种新类似 std::byte ,而 Windows 头文件里自带一种类型 byte


这两种类型本身并不冲突,因为一个是 std::byte,另一个是 byte


但是!!!,如果代码里广泛使用了using namspace std;再遇到 byte 的时候,编译器就不知道它是 Windows 的 byte 还是 std:byte 省略了 std。所以,尽量少在工程里包含这种"大杀器"。你如果想省事,可以在自己的 .cpp 文件里使用(.cpp 不暴露声明)。实在想在 .h 里用(为省事),尽量使用诸如 using std::vector; 之类的,用哪个暴露哪个,而不是一次性全部暴露。


D:


《C++ Primer Plus (第六版 中文版 人民邮电出版社)》第九章: 内存模型和名称空间 第 328 页:

“有关 using 编译命令和 using 声明,需要记住的一点是,他们 增加了名称冲突的可能性。”


《C++ Primer Plus (第六版 中文版 人民邮电出版社)》第九章: 内存模型和名称空间 第329页:


一般说来,使用 using 命令 比 使用 using 编译命令 更 安全 ,这是由于它只导入了制定的名称。

如果该名称与局部名称发生冲突,编译器将发出指示。using 编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则 局部名称将覆盖名称空间版本 ,而编译器并不会发出警告。

另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。

然而名称空间的支持者希望有更多的选择,既可以使用解析运算符面也可以使用 using 声明,也就是说,不要这样做:


19.png19.png19.png

19.png

而应这样做


20.png


或者这样做

21.png所以,总之:头文件里不要用 using namespace。因为头文件内容相当于一段代码的公开部分,会在预处理阶段被替换进引用者的源文件里。

具体命令操作查看:


22.png


使用 using namespace 会对引用者产生侵入性,使得引用你的头文件有很多未知的副作用。不仅 using namespace,任何 using 都是要尽量避免的。任何类型函数都应该写全名。


如果在源文件中用 using namespace 就是个人的选择了。特别是项目小没有很多重名的时候。如果你看到 Google c++ style guide 上说不要用 using namespace std,更多是因为代码库里有很多 std 的补充替代品,比如 absl。使用时注明用的是哪个可读性比较好。



目录
相关文章
|
存储 C# 数据库
C# 生成唯一ID,有哪些方法?
【2月更文挑战第12天】
1900 0
如何解决vscode中文路径的问题
如何解决vscode中文路径的问题
2071 0
|
Oracle Java 关系型数据库
在macOS系统中 下载、安装、使用Java8
在macOS系统中 下载、安装、使用Java8
17616 0
在macOS系统中 下载、安装、使用Java8
|
运维 监控 数据安全/隐私保护
HTTPS 证书自动化运维:HTTPS 证书管理系统之使用指南
本文详细介绍【灵燕空间HTTPS证书管理系统】(https://www.lingyanspace.com)的配置与使用,涵盖注册账户、邮箱配置及证书自动签发、监控和部署的一体化指南。通过页面顶部菜单的【视频教程】和【图文教程】,帮助用户从注册到实际应用全面掌握系统操作。最新迭代后,泛域名证书已包含根域名,无需额外申请多域名证书。
|
算法 定位技术
技术笔记:Kriging插值法
技术笔记:Kriging插值法
573 1
|
设计模式 算法 架构师
软考软件设计师:是否值得报考?详尽分析与建议
软考软件设计师是我国IT领域权威认证之一,涵盖软件设计、系统分析、架构设计等多方面知识。
1009 1
|
监控 Shell 数据处理
Python执行Shell并获取结果的全面指南
Python执行Shell并获取结果的全面指南
1393 1
|
安全 数据处理 C#
深入理解C#中的Span<T>和Memory<T>
【1月更文挑战第8天】本文旨在探讨C#中引入的两个重要类型:Span<T>和Memory<T>。它们为开发者提供了一种高效且安全的方式来处理内存中的数据。文章首先介绍这两个类型的基本概念和用途,接着深入分析它们的工作原理和适用场景,并通过代码示例展示如何在实际应用中使用它们。
|
负载均衡 数据安全/隐私保护 网络架构
理解网络交换机:L2与L3交换机的功能与区别
理解网络交换机:L2与L3交换机的功能与区别
2705 0