【问题标题】:How to properly use namespaces to avoid name collision?如何正确使用命名空间以避免名称冲突?
【发布时间】:2011-02-22 15:40:09
【问题描述】:

我对正确使用 C++ 命名空间有点困惑。我很清楚它们如何帮助避免冲突(名称冲突),但对于 using 关键字就不清楚了。我的意思是,假设我将一部分代码放入命名空间并创建一个类,比如

namespace my
{
    class vector { ... };
}

当然,当我使用它时,我不想一直输入my::vector,所以我想输入using namespace my。但是,我最终可能需要来自 std 命名空间的东西,然后我同时想要 using namespace std,但这会让我回到最初的名称冲突问题。

我知道可以只“导入”我需要的功能,例如using std::set,但在这种情况下,像我一样完全导入标准命名空间stdmy 命名空间似乎很自然。 d 一直使用它们。

这是否意味着即使我使用命名空间,我仍然应该考虑为我的类型赋予非通用名称?或者using namespace 是一个错误,我应该总是输入my::vector 来代替?谢谢。


好吧,我可能应该澄清一下,这更多的是可读性问题,而不是打字问题。很多:: 在我看来真的很奇怪。我知道这是品味和习惯的问题,但无论如何。

【问题讨论】:

  • "我不想一直输入my::vector" 为什么不呢?完全限定名称(或对长名称空间名称使用名称空间别名)有助于使您的代码更清晰(无需猜测名称的来源)。它还可以帮助您避免在使用 using 指令(尤其是 using namespace std;)时可能发生的有害名称查找问题。此类名称查找问题不会经常发生,但当它们确实发生时,它们可能难以诊断,而且我已经在 Stack Overflow 上回答了多个关于由 @ 引起的问题的难题987654335@.
  • @James:主要动机不是打字,而是可读性。可能这是品味和习惯的问题,但目前到处都是:: 真的让我更难阅读。
  • @James:在嵌套命名空间的情况下,情况会变得更糟,my::db::helpers::class(随机示例,请不要太认真)对我来说真的很糟糕:)
  • @7vies:你上一条评论的问题可以用namespace dbhelp = my::db::helpers;解决
  • @7vies:它仍然比 my_db_helpers_class 更容易(因为命名空间别名和使用声明/指令),这是在没有命名空间的可管理代码中得到的。也就是说,我经常希望你可以在那里使用句点而不是双冒号。

标签: c++ namespaces


【解决方案1】:

当然,当我使用它时,我不想一直输入 my::vector,所以我想使用命名空间 my.但是,我最终可能需要 std 命名空间中的一些东西,然后我想同时使用命名空间 std,但这会让我回到最初的名称冲突问题。

是的,它带您回到最初的名称冲突问题。这就是为什么你应该谨慎使用using namespace ...; 指令,并且只在源文件中,从不在头文件中

这是否意味着即使我使用命名空间,我仍然应该考虑为我的类型赋予非通用名称?

不,你不应该。命名空间正是为了避免这种情况而发明的。

或者使用命名空间是一个错误,我应该总是输入 my::vector 代替?

如果需要,您可以使用 using namespace ...;using ...; 指令,直到发生冲突。这意味着当您确实发生冲突时,您最终会通过在某些地方明确限定名称来编写“不自然”的代码。

实际上,当您处理短命名空间名称(即std)时,您可以一直显式地键入它们。大约一周后,您甚至不会注意到您正在输入它。

【讨论】:

  • 理想情况下,如果要使用 using 指令,应该在函数范围内使用它,这样便于跟踪。
  • +1 表示“你甚至不会注意到你正在输入它”。我已经不再将using namespace 放在文件范围内,并且很少输入using 指令(仅适用于在整个模块或函数中弹出的标准类型)。
  • @James:确实,我也求助于那个令人痛苦的长命名空间!
【解决方案2】:

如果您的代码同时使用std::vectormy::vector,那么最好始终写完整名称。

【讨论】:

    【解决方案3】:

    如果您要立即再次打开命名空间,为什么还要把它放在命名空间中呢?您也可以将类放在全局命名空间中!

    对于那些没有注意到文件顶部的 using 指令的人来说,这个向量不是 std::vector 也会很困惑。这本身就是编写 my::vector 的原因!

    对我来说,看到像 std::vector 和 std::list 这样的名称实际上提高了可读性,因为我立即知道这些名称的含义。

    【讨论】:

    • 当然,我不会在任何地方再次打开它,主要是在那些命名空间中的类被大量使用的 .cpp 文件中,因此它与使它们全局化并不完全相同。我仍然不同意::,因为我发现它们在视觉上分散了太多注意力。我实际上同意@Fred Nurk 使用句点代替冒号的能力(如在 Java/Python/C# 中)将非常有帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多