gpt4 book ai didi

c++ - 是否有 'right' 方法来处理 C++ 中的命名空间

转载 作者:可可西里 更新时间:2023-11-01 18:11:46 29 4
gpt4 key购买 nike

我被 Java、C# 和 AS3 感染了,我一直想以同样的方式使用 C++ 命名空间,但我一直在读到,它们的设计并没有真正考虑到这一点。

有没有正确的方法来使用命名空间?例如,在由十几个库项目(比如图形、声音、数学等)和几个应用程序项目组成的代码库中,该怎么办?是否正确/错误/开发人员偏好:

  • 把一切都放在顶级 MyCompanyNameMyProjectName命名空间?
  • 为每个库拥有一个(子)命名空间

  • 是否有官方规则/指南作为 C++ 的一部分,或者只有人们倾向于遵循的建议?

    最佳答案

    正如我在对@Nim 的回答的评论中提到的,关键是要提出一个实用的结构。

    如果你看一下 .NET 框架,它的命名空间有很长的名字并且嵌套很深(比如 System.Collections.Generic.List<T>)。这同样适用于 Java。对于大量嵌套的命名空间,您有很长的名称,但没有任何影响。

    我第一次创建 List 类时,会遇到名称冲突,这正是命名空间应该防止的。 (因为这似乎给了评论者错误的想法,所以我当然可以创建自己的 List 类。但是每次使用它时,我都有可能遇到冲突。“标准” List 或其命名空间都是非常常用,所以我很有可能在该命名空间上有一个 using,这意味着,如果我还想在同一个文件中引用我自己的 List 类,我会遇到冲突)

    相比之下,C++ 标准库将几乎所有内容都放在一个简单的 std 命名空间中(以及 std::ios 中的一些内容)

    实际上,.NET 命名空间确实是在浪费精力。它们没有效果。每个代码文件都以一长串 using X; using Y; using Z 开头,因此最终效果是在您编写代码时实际上没有任何命名空间有效。为了创建一个整数列表,我只做 List<int> 。命名空间基本上没有了。

    在 C++ 中,不鼓励人们使用 using namespace std ,因此为了使用标准库符号,我们使用 std 前缀: std::vector<int>

    Boost 使用类似的东西:几乎所有东西都在 boost 根命名空间中。然后将一些复杂的库放置在子命名空间中,例如 boost::filesystem 。或 boost::mpl ,并且一些库具有“仅供内部使用”的命名空间,通常命名为 aux ,但它们旨在让用户不可见(或至少忽略)。

    这更好地保留了命名空间的优势:它们避免了命名冲突。我可以(人们经常这样做,因为 vector 可以有几个不同的含义)定义我自己的 vector 类,它不会与 std::vector 冲突。

    那么你的命名空间应该嵌套多深?我倾向于使用标准库之类的东西,再加上一点。不要为所有东西发明新的命名空间,并保持命名空间名称的简短。

    也许您公司的所有代码都使用一个公共(public)根命名空间,例如 Cpy

    在此之下,您可能为每个产品都有一个命名空间,例如 Prod 。过去了?好吧,您可能为每个主要组件( Comp )都有一个命名空间,基本上就是这样。

    重要的是,您几乎永远不必引用最外层的命名空间。您编写的代码将在 Cpy::Prod 内,因此您唯一需要输入的命名空间前缀是 Comp:: ,它简短明了,就像标准库 std 一样。我几乎不需要写 Cpy::Prod::Comp ,因为我的所有代码都已经在前两个命名空间中了。如果不是这种情况,命名空间结构将太长且嵌套太深。

    然后我有时喜欢 Boost,并创建小的“内部”助手命名空间,通常称为 AuxUtil 或类似名称。这些应该很小,并且只能从它们的直接父命名空间访问。一个特定的组件可能有一些仅供内部使用的类。所以它们被隐藏在一个小的 Aux 命名空间中,主要是为了让它们对引用我们组件的其他人隐藏。

    当然,您可能会问自己,最外面的“公司” namespace 究竟有什么用途。我们所有的代码都是我们公司的,这难道不是理所当然的吗?并且第三方代码通常(希望)在其自己的命名空间内(例如 boost:: ),因此即使没有公司命名空间,我们也不应该冒任何冲突的风险。你可能想删除那个。

    另一件要考虑的事情是,如果您正在编写供外部使用的库组件,那么命名空间结构应该更短。在公司内部,您可以假设每个人都已经在“公司” namespace 内编写代码,因此他们不必键入 namespace 前缀。它基本上是“免费的”。但是,如果外部用户必须引用您的代码,那么他们必须输入额外的命名空间层,这会很快过时。整体的“产品”命名空间可能是不可避免的(类似于 stdboost ),但是您可能希望尽可能避免使用“产品”命名空间。 (同样,像这两个一样,很少在根命名空间下创建子命名空间)

    最重要的是,您的命名空间必须实用且可用。如果你强制用户在命名空间前缀中输入超过 8 个字符,那就很烦人了,他们会开始把 using namespace X 放在任何地方。你只需要命名空间,否则你可能会遇到名称冲突。您控制的代码永远不应该与第三方代码共享命名空间,因为您无法控制它们添加的名称(通常,第三方库通过将它们的库放在公共(public)根命名空间中来处理此问题,例如 boost ) .但是在您控制的代码中,不会有那么多冲突。所以不要定义比你实际需要更多的命名空间。

    关于c++ - 是否有 'right' 方法来处理 C++ 中的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4076328/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com