支持功能声明应该去哪里?

时间:2012-05-22 10:49:36

标签: c++ header-files private-header

我有一个.cpp源文件,其中包含一些需要公开访问的函数和一些仅在此源文件中使用的支持函数。

我一直在头文件中放置这些函数声明的 所有 ,因为我个人觉得在一个地方看到一个类提供的所有东西都很有用。但是,我想指出这些函数是否供内部使用,类似于private访问修饰符,但不使用类(它们是独立函数)。

一些可能的解决方案是:

  • 将私有声明放在源文件中。
  • 将私有声明放在单独的标题中。

这两种解决方案都将公共和私有功能分成了我想避免的单独文件。

4 个答案:

答案 0 :(得分:6)

如果这些功能不是供公众使用的,则不应将其放入标题中。将它们放入它们使用的源文件中。

要完全隐藏这些函数,不要在源文件之外使用,通常会执行以下操作之一:

  • 函数声明为static
  • 将函数放入未命名的namespace

后者被认为是优选的。实际上,C ++标准7.3.1.1规定:

  

在声明命名空间作用域中的对象时,不推荐使用static关键字,unnamed-namespace提供了一个更好的选择。

有关未命名的命名空间与静态的更多讨论,请参阅Unnamed/anonymous namespaces vs. static functions和相应的comp.lang.c++.moderated thread

答案 1 :(得分:3)

如果私有函数仅用于单个源文件,则不需要任何额外的头文件。只需将功能标记为static或使用匿名namespace

如果可以从许多源文件中使用这些函数,请在特殊的namespace中的单独头文件中声明它们。这是我的建议。

答案 2 :(得分:0)

  

支持函数声明应该去哪里?

他们不必去任何地方。将它们设置为静态并将它们保存在源文件中。如果它们仅用于单个源文件,则无需在任何标头中提出声明。

答案 3 :(得分:0)

你没有提到这些'函数'是否是一个类的成员,但我会假设它们是。如果是这样,我建议您查看'pimpl idiom'。基本上这意味着将你想要保密的全部或大部分内容放入一个单独的类中,然后只在类声明中指向一个类的实例。例如:

class MyClass
{
    // ... some stuff
private:
    SecretObject obj_;
    int hiddenCall();
};

变为

class MyClassImpl;

class MyClass
{
private:
    MyClassImpl* impl_;
};

然后,我们的想法是,您的实现类的所有声明和定义都将进入您的.cpp文件,该文件将其隐藏在除编译单元之外的任何内容中。这种方法有许多重要的优点:

  • 隐藏实现,因此公开的标题不会给予太多的实现。
  • 可以通过删除标题中的依赖来提高编译速度 - v。如果标题包含很多,则很重要。
  • 对于'绝缘'客户端代码对于他们不需要构建的库(例如数据库API等)非常有用。

有许多缺点:

  • 如果代码隐藏在cpp文件中,可以使单元测试更加棘手。我个人认为更好的解决方案是拥有一个单独的私有标头和实现文件,以便您可以控制代码的客户端,但测试工具仍然可以充分测试它。您只需在cpp文件中包含MyClassImpl标头,但不要将其包含在MyClass标头中 - 这会使对象失败。
  • MyClassMyClassImpl之间的间接对代码/管理来说可能很烦人。

一般来说,这可能是实现你想达到目标的最佳方式。请阅读Herb Sutter的文章,以获得更深入的解释。

另一方面,如果你在讨论自由函数,与该类没有直接关系,那么我会将它们放在你的cpp文件中的未命名的命名空间中。例如:

namespace {

    // Your stuff goes here.

};

同样,如果采用这种方法,你就会遇到如何访问这些函数的单元测试问题,但是如果这确实是个问题,可能会解决这个问题,可能是通过创建特定的命名空间,条件编译等。理想,但可能。