c++ - 为什么以及如何在 C++ 中使用命名空间?

标签 c++ namespaces

我以前从未在我的代码中使用过命名空间。 (除了使用 STL 函数)

  1. 除了避免名称冲突,还有其他理由使用命名空间吗?
  2. 我必须将声明和定义都包含在命名空间范围内吗?

最佳答案

经常被忽视的一个原因是,只需更改一行代码以选择一个命名空间而不是另一个命名空间,您就可以选择一组替代的函数/变量/类型/常量 - 例如另一个版本的协议(protocol),或单线程与多线程支持,对平台 X 或 Y 的操作系统支持 - 编译和运行。通过包含具有不同声明的 header 或使用 #defines#ifdefs 可能会实现相同的效果,但这会粗略地影响整个翻译单元,如果链接不同版本您可以获得未定义的行为。使用命名空间,您可以通过 using namespace 进行选择,这些选择仅适用于事件命名空间,或者通过命名空间别名进行选择,因此它们仅适用于使用该别名的地方,但它们实际上被解析为不同的链接器符号,因此可以在没有的情况下组合未定义的行为。这可以以类似于模板策略的方式使用,但效果更加隐含、自动和普遍——这是一个非常强大的语言特性。


更新:解决 marcv81 的评论...

Why not use an interface with two implementations?

“接口(interface) + 实现”在概念上是为上面选择一个命名空间的别名所做的,但如果你的意思是 runtime 多态性和虚拟调度:

  • 生成的库或可执行文件不需要包含所有实现,并且在运行时不断将调用定向到选定的实现

  • 作为一种实现,编译器可以使用无数优化,包括内联、死代码消除,以及“实现”之间不同的常量可以用于例如数组大小 - 允许自动内存分配而不是较慢的动态分配

  • 不同的命名空间必须支持相同的使用语义,但不一定支持与虚拟调度完全相同的一组函数签名

  • 使用命名空间,您可以提供自定义的非成员函数和模板:这对于虚拟调度是不可能的(并且非成员函数有助于对称运算符重载 - 例如支持 22 + my_typemy_type + 22)

  • 不同的命名空间可以指定不同的类型用于特定目的(例如,哈希函数可能在一个命名空间中返回 32 位值,但在另一个命名空间中返回 64 位值),但虚拟接口(interface)需要统一静态类型,这意味着像 boost::anyboost::variant 这样的笨拙和高开销的间接寻址,或者是高位有时无意义的最坏情况选择

  • 虚拟调度通常涉及胖接口(interface)和笨拙的错误处理之间的妥协:对于命名空间,选项可以在没有意义的命名空间中简单地不提供功能,从而在编译时强制执行必要的客户端移植工作

关于c++ - 为什么以及如何在 C++ 中使用命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4211827/

相关文章:

java - JAXB 强制命名空间 URI - 为什么它期望某些命名空间,即使它没有定义?

c++ - 使用 std::map 的 Miniheap lambda

c++ - 如何使它成为一个数组?

php - Laravel 工厂辅助函数如何在命名空间方面工作?

c++ - 防止创建成员函数都是静态的类

Python - 如果部署到两个不同的路径,命名空间会发生冲突

在 C++ 中具有多个枚举参数的 C++ 函数模板部分特化?

c++ - 这个列表是垃圾内存吗?

c++ - 映射#include 的工具

c++ - 名称查找和声明点概念