C ++命名空间Noob需要帮助

时间:2013-06-12 03:23:38

标签: c++ namespaces

我遇到了一些关于我希望修复的代码样式的怪癖,即使用命名空间。首先我要说的是,我目前在我的特定项目中担任唯一的软件工程师,并且没有更多的高级工程师来指导和协助我。我发现这特别令人担忧,因为我担心我正在开发真正的hacky做法,当我试图在不久的将来换工作时会让我笑出房间。

最近,我一直关注并遵守Google风格指南。当我得知我使用“使用命名空间std”的过程时,我感到有点震惊。不满意。一般来说,我的大部分项目都相对较小,几乎没有机会重复使用我的课程。但是,既然我已经做了更多的研究和研究,我就会意识到为什么我的实践不受欢迎,我正在寻求改进我使用命名空间和范围操作符的方式。因此,我有以下问题:

  1. 何时最好定义新的命名空间?我知道这是一个奇怪的问题,我知道不属于某个类的函数或变量可以在命名空间中组合在一起。但是,假设我有一个仅由课程组成的课程。不定义命名空间是不好的做法吗?或者是否应该为项目创建一个新的命名空间,以防有人想要在以后与它进行交互?

  2. 我知道这有点令人讨厌,但是什么时候使用“std ::”好?我问,因为我最近读到了如何更好地使用C标准库的“包装”版本(例如,cstdlib与stdlib.h)。我将一些源代码更改为实验。我立刻发现G ++并没有因为没有使用std :: printf()而不仅仅是printf()而对我大喊大叫。我现在的问题是,我在哪里停止明确的范围放置?例如,编译器不会对我大喊大小关于size_t或uint8_t,我是否还必须在其前面放置“std ::”?什么是最佳做法?

  3. 仅考虑使用您正在使用的功能时,“ok”是否正在考虑“使用”?也就是说,我正在谈论我有一个类并且会做类似“使用std :: endl;”的情况。在实现特定类的.cpp文件中。

  4. 编辑添加第四个问题: 4.在为派生类编写代码时,每当从基类调用函数时执行“Baseclass :: function()”是否有意义,即使基类中的函数不是虚拟的并且不能重载?这会妨碍或提高可读性吗?

    感谢所有帮助。我发现这个网站是一个很好的资源!

3 个答案:

答案 0 :(得分:2)

这些做法多年来一直很好用。希望你觉得这很有帮助。

1)命名空间是一种组织技术,用于将类似的东西放在一起,通常用于发现,并避免与其他代码发生名称冲突。当您使用支持intellisense的IDE时,它们可以成为一个很好的帮助,使得编码变得容易,而无需退回到文档来查找内容。过分细粒度的命名空间可能对您的代码没有名称空间有害。虽然这里没有硬规则,但是如果你一直为少于3-4个项目的组创建新的命名空间,那么你可能过度了。您通常也不会在.cpp文件中定义新的命名空间,因为这是唯一可以看到它的文件。我很少看到另一个极端的例子。

使用模板时,所有内容都在标题中,我喜欢在主命名空间下创建一个“详细信息”命名空间,以将模板库的“私有”类与实际预期使用的内容隔离开来。还有其他方法可以实现类似的结果,提供更好的封装,但它们也需要更多的维护工作。

2)使用语句通常应该在C ++文件中隔离,而不是放在标题中,否则你会在大型项目中很快忘记“使用”的内容。同样,如果标头不隐式依赖于使用语句,那么最好是可移植性和可维护性。您可以通过在包含语句后立即放置using语句来轻松避免这种情况。

// main.cpp
#include "myheader1.h" // can't see using namespace std, ok.

using namespace std;

// Does this have std:: in front of everything that needs it? 
// Maybe. Compiler won't tell me...
#include "myheader2.h" 

从不在打开的命名空间中放置using语句。也就是说,除非你真的,真的想让人们头脑旋转。这可能不会像你(或下一个人)期望的那样起作用。

namespace A { ... }

namespace B {
  using namespace A; // Don't do it!
}

在某些情况下,对于绝对无处不在的命名空间,我看到人们在预编译头文件中使用语句(这只是一个VC ++的东西?)。我发现这是可以忍受的,因为它们通常是较小的代码本地,但即使在那里,我认为它是一个延伸。它可以促进上面提到的头依赖问题。

3)这种做法可能会变得很麻烦,因为你会发现你必须继续回去“再做一件事”并且可能会让人感到困惑(“等等,对于这个文件,我使用数学:: vector,physics :: vector or std :: vector?“)。如果由于冲突问题而无法使用整个命名空间,则最好至少明确一个命名空间。如果有很多重叠,也许可以明确两者。

在极少数情况下,使用深度嵌套的命名空间,编写类似这样的内容可能很有用:

using namespace this::thing::is::ridiculous::someone::should::trim::it = ludicrous;

允许使用短名字引用命名空间,例如

auto p = new ludicrous::SomeClass();

如果要这样做,则应在整个代码库中为您执行此操作的命名空间建立一致的约定。如果您在3个不同的地方使用3个不同的名称,则只会使代码的可读性降低。

答案 1 :(得分:1)

  1. 任何旨在完全可重用的东西都应该使用命名空间。任何名称都有可能存在名称冲突的东西应该使用命名空间,这意味着几乎任何东西。对于较小的项目,它更重要,但总的来说,一切都应该进入某种命名空间。

  2. 基于C ++标准,来自C ++标准头的任何内容都将位于命名空间std中。它们也可能被拉入全局命名空间。因此,您最好使用std::printfstd::uint8_t等来获得最大的便携性。

  3. 这是一个偏好问题。对于std::命名空间中的基本内容,我宁愿亲自明确,因为键入的字符很少。对于高度嵌套的命名空间名称(如boost的某些部分,其中有3个以上的命名空间要经过),那么using更有意义。

答案 2 :(得分:0)

我的偏好是使用std :: cout,例如:: FunctionName()。 1.在我看来,这使得代码的评论者/读者可以明显/明确地使用 2.“using namespace”最终包含该命名空间的所有类,因此可能导致与您的类/函数名冲突。 3.如果有人知道无论开发什么,那么在自己的命名空间中创建它的库是必须的。 4.对于不打算开发/连接到第三方的类,我不打算使用命名空间。

如果这回答了您的问题,请告诉我。否则请回来查看更多细节。