在我阅读的一个项目中,有两个 header files 和同一个 class 的两个声明。一个由使用此库的程序使用,用作接口。另一个是库本身使用的。接口头文件比较简单。它不包含私有成员并且具有较少的方法。即使出现在两个文件中的方法也可能不会以相同的顺序出现。我想知道同一个 class 有 2 个 header files 是否合法?如果不是,可能的后果是什么?
回答1
简而言之
这根本不合法。根据提交的私有部分中的内容,它可能适用于某些实现,但它很可能在编译器的第一次更改或新版本时失败。只是不要。有更好的方法来实现预期目标。
更多解释
为什么不合法?
这是https://Definitions%20and%20ODR%20(One%20Definition%20Rule)。它在标准中定义,在很长的部分 [basic.def.odr]
中。总之,可以在不同的编译单元(例如您的代码和库的代码)中对相同的 class 进行多个定义,但前提是它的定义完全相同。这要求用于两个定义的标记序列完全相同,如果省略私有成员,情况显然不是这样。 (请注意,还有额外的要求,但第一个已经坏了,所以我短路了)。
为什么即使不合法,它在某些情况下也能在实践中发挥作用?
这纯粹是依赖于实现的运气。我不会发展这个话题,以免鼓励危险行为。
有什么选择
只需在任何地方使用相同的 class 定义。私人成员是私人的,那么将他们留在原来的位置有什么风险?
好的,有时私有成员的定义还需要披露私有类型,以连锁反应结束,太多了。在这种情况下,您可能会想到:
- 简单的https://en.wikipedia.org/wiki/Opaque_pointer 技术,它使用指向私有实现class 的指针,其类型已声明但未在不需要知道的编译单元中定义。
- 更精细的 https://en.wikipedia.org/wiki/Bridge_pattern,它允许为抽象构建 class 层次结构,并为实现构建 class 层次结构。它可以以与不透明指针类似的方式使用,但允许不同类型的私有实现 classes (这是一个复杂的模式,如果它只是为了隐藏私有细节,那就有点矫枉过正了)。