详解:为什么尽量不要使用 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。使用时注明用的是哪个可读性比较好。



目录
相关文章
|
1月前
|
C语言 C++
C++(六)Namespace 命名空间
命名空间(Namespace)是为了解决大型项目中命名冲突而引入的机制。在多库集成时,不同类库可能包含同名函数或变量,导致冲突。C++通过语法形式定义了全局无名命名空间,并允许对全局函数和变量进行作用域划分。命名空间支持嵌套与合并,便于协同开发。其使用需谨慎处理同名冲突。
|
4月前
|
C++
c++中的using namespace std;
c++中的using namespace std;
|
5月前
|
编译器 数据安全/隐私保护 C语言
C++ 之命名空间namespace【详解】
C++ 之命名空间namespace【详解】
|
安全 程序员 C语言
命名空间和using namespace std的详解【C++】
命名空间和using namespace std的详解【C++】
|
10月前
|
安全 C++
【C++】从认识using namespace std开始进入C++的学习
【C++】从认识using namespace std开始进入C++的学习
51 0
|
10月前
|
算法 编译器 C语言
C++ | 你真的了解namespace吗?
C++ | 你真的了解namespace吗?
45 0
|
11月前
|
前端开发 容器
什么是space-around
什么是space-around
117 0
|
Kubernetes 容器
k8s的Namespace详解
k8s的Namespace详解
147 0
|
编译器 C++
using namespace std 是什么意思——C++命名空间
using namespace std 是什么意思——C++命名空间
254 0
【为什么】在大型项目中为什么不能用using namespace std;
【为什么】在大型项目中为什么不能用using namespace std;