我有一个 .cpp 源文件,其中包含一些需要公开访问的功能和一些仅在此源文件中使用的支持功能。
我一直将所有这些函数声明放在头文件中,因为我个人发现在一个地方查看类提供的所有内容很有用。但是我想指出这些函数是否供内部使用,类似于private
访问修饰符,但不使用类(它们是独立函数)。
一些可能的解决方案是:
- 将私有声明放在源文件中。
- 将私有声明放在单独的标题中。
这两种解决方案都将公共和私有功能拆分为单独的文件,我想避免这样做。
我有一个 .cpp 源文件,其中包含一些需要公开访问的功能和一些仅在此源文件中使用的支持功能。
我一直将所有这些函数声明放在头文件中,因为我个人发现在一个地方查看类提供的所有内容很有用。但是我想指出这些函数是否供内部使用,类似于private
访问修饰符,但不使用类(它们是独立函数)。
一些可能的解决方案是:
这两种解决方案都将公共和私有功能拆分为单独的文件,我想避免这样做。
如果函数不是供公众使用的,则不应将其放入标题中。将它们放入使用它们的源文件中。
要完全隐藏这些函数以防止在源文件之外使用,通常需要执行以下操作之一:
static
.namespace
.后者被认为是可取的。实际上,C++ 标准 7.3.1.1 规定:
在命名空间范围内声明对象时,不推荐使用 static 关键字,未命名命名空间提供了更好的选择。
有关未命名命名空间与静态的更多讨论,请参阅未命名/匿名命名空间与静态函数和相应的comp.lang.c++.moderated 线程。
如果私有函数只在单个源文件中使用,那么您不需要任何额外的头文件。只需标记函数static
或使用匿名函数namespace
。
如果可以从许多源文件中使用这些函数,请在一个单独的头文件中以特殊的namespace
. 这是我的建议。
支持函数声明应该去哪里?
他们不必去任何地方。使它们成为静态并将它们保存在源文件中。如果它们只在单个源文件中使用,则无需在任何标题中提出声明。
你没有提到这些“函数”是否是一个类的成员,但我会假设它们是。如果是这样,我建议您查看'pimpl idiom'。基本上,这意味着将您想要保持私有的所有或大部分内容放入一个单独的类中,然后在您的类声明中只有一个指向该类实例的指针。例如:
class MyClass
{
// ... some stuff
private:
SecretObject obj_;
int hiddenCall();
};
变成
class MyClassImpl;
class MyClass
{
private:
MyClassImpl* impl_;
};
然后的想法是,您的实现类的所有声明和定义都将进入您的 .cpp 文件,该文件将其隐藏在编译单元之外的任何地方。这种方法有许多重要的优点:
有很多缺点:
MyClassImpl
标头包含在您的 cpp 文件中,但不要将其包含在MyClass
标头中 - 这会破坏对象。MyClass
和之间的间接MyClassImpl
编码/管理可能会令人厌烦。不过,一般来说,这可能是实现您想要达到的目标的最佳方式。查看 Herb Sutter 的文章以获得更深入的解释。
另一方面,如果您谈论的是与类没有直接关系的自由函数,那么我会将它们放在您的 cpp 文件中的未命名命名空间中。例如:
namespace {
// Your stuff goes here.
};
同样,如果您采用这种方法,您会遇到如何访问这些函数的单元测试问题,但如果这确实是一个问题,则可以通过创建特定的命名空间、条件编译等来解决这个问题。不理想,但可能的。