C++里面的using namespace是什么
在学 C++ 的过程中,我对一句话很困惑:
1 | |
一开始我下意识把它理解成 Python 里的“导入包”,类似:
1 | |
然后就可以用 math.sqrt() 之类的函数。但后来发现,好像又不完全是这么回事。
按照我最初的理解:
using namespace std = 把 std 这个库“导入进来”
但很快发现不对。
因为在 C++ 里,真正“引入库”的是:
1 | |
如果不写这个,
就算写了 using namespace std;,cout 还是不能用。
这说明:
using namespace 并不是“导入功能”
那它到底干嘛?先从代码上来说,不加namespace要这样写:
1 | |
而加了using namespace std;
可以写:
1 | |
按照官方的解释,这里的 std:: 是一个命名空间前缀
cout其实是std这个“作用域”里的名字- 就像一个“名字分组”的容器
“把 std 这个命名空间里的所有名字,拉到当前作用域里”
emmmm还是很难懂。
还是举一个例子吧:
我自己写了两个库:分别是libraryA.cpp和libraryB.cpp
1 | |
1 | |
而在libraryA.h 和 libraryB.h,都有:
1 | |
然后在 main 里写:
1 | |
结果直接报错:冲突,因为编译器不知道你要用哪个 add。
那么可以理解为,namespace的作用是为了 避免命名冲突,更官方点来说:
using namespace 不是“导入模块”,而是“把名字展开”
展开之后:
1 | |
💥 两个同名函数直接撞在一起
所以在C++里面:
1 | |
是“去掉命名空间”,直接用裸名字
这其实更像 Python 的:
1 | |
而不是 import math,因为(call back 开头)如果只是import math 调用sqrt()也还是需要 math.sqrt()而不是直接sqrt()
那么也变相解释了:为什么python不会出现这个问题?
因为名字是“带命名空间”的,不会冲突。
总结一下,为什么会有 namespace?
不同库可以放心写:
1 | |
只要放在不同 namespace 里就不会打架:
1 | |
最最最后,
#include:把声明“拿进来”namespace:给名字“分组,防冲突”using namespace:把名字“展开到当前作用域”
一个小小的C++ coding习惯尽量避免写:
1 | |
而是写:
1 | |
因为:
👉 写清楚来源,比省这点字更安全。