我有一个.cpp源文件,其中包含一些需要公开访问的函数和一些仅在此源文件中使用的支持函数。
我一直在头文件中放置这些函数声明的 所有 ,因为我个人觉得在一个地方看到一个类提供的所有东西都很有用。但是,我想指出这些函数是否供内部使用,类似于private
访问修饰符,但不使用类(它们是独立函数)。
一些可能的解决方案是:
这两种解决方案都将公共和私有功能分成了我想避免的单独文件。
答案 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文件,该文件将其隐藏在除编译单元之外的任何内容中。这种方法有许多重要的优点:
有许多缺点:
MyClassImpl
标头,但不要将其包含在MyClass
标头中 - 这会使对象失败。MyClass
和MyClassImpl
之间的间接对代码/管理来说可能很烦人。一般来说,这可能是实现你想达到目标的最佳方式。请阅读Herb Sutter的文章,以获得更深入的解释。
另一方面,如果你在讨论自由函数,与该类没有直接关系,那么我会将它们放在你的cpp文件中的未命名的命名空间中。例如:
namespace {
// Your stuff goes here.
};
同样,如果采用这种方法,你就会遇到如何访问这些函数的单元测试问题,但是如果这确实是个问题,可能会解决这个问题,可能是通过创建特定的命名空间,条件编译等。理想,但可能。