c++:跨pimpl实现共享代码

c++: shared code across pimpl implementations

本文关键字:共享 代码 实现 pimpl c++      更新时间:2023-10-16

我目前正在编写一些必须是可移植的代码。出于这个目的,我使用了pimpl习语,因为我认为它将实际实现与API清晰地分离开来。无论如何,只有在实现不共享代码的情况下(例如,在实现之间共享一些泛型函数),pimpl习语才非常有效。

我猜另一个选择是抽象接口。-无论如何,因为我在整个项目中使用pimpl,我真的不认为将它与抽象接口(在API级别)混合是一个好主意。

那么你会建议在不同的痘痘之间共享代码吗?我想过为粉刺本身设计一个抽象的接口类,这样实际的API就可以清晰地分开,但这似乎也是一个奇怪的想法。

PS:我不想讨论是抽象接口好还是抽象接口好。从API的角度来看,我决定用粉刺,我想坚持下去。

您可以将共享代码移动到一个新的独立类、命名空间或模块中。

VTK有很棒的PIMPL设计。检查它!

以下是VTK编码标准

您的类模型可以包含抽象类,即使实现中包含了pip。两者正交

然而,如果你把你所有的私有方法放入你的粉刺中,可能会有一些障碍要跳过。调用实例方法,无论在何处定义,都需要一个指向实例的指针。可以将实例指针作为pimpl方法的参数提供,也可以在外部类的私有方法中隐式地提供。

另一个选择是通过组合而不是继承来共享,这有其自身的优点。

如果您实现PIMPL的细节是可重用的,那么您不应该为将它们公开而感到难过。关键是要保持界面整洁。

有时候你想要共享那些不应该在外部使用的帮助程序。此时,清楚地记录不应该重用的东西是您试图解决的真正问题。我喜欢使用detail/private头。

// Implementation details, not for reuse
namespace some_public_ns {
namespace detail {
  // .. shared code
}}

通常你会把这些细节代码放在它自己的头中。组织通常会选择一个约定来命名,以避免混淆。

thingajig.h
thingajig_priv.h
thingajig_detail.h
它不会让带着猎枪的人离开你的客厅。我会说你不应该尝试。但是,不小心拉入这些共享代码真的很难。

然后在你的cpp文件中重用代码,你可以只把细节命名空间包含在一个命名空间中。

namespace some_public_ns {
namespace {
  using namespace detail;
}}

这允许您在名称空间中避免混乱,但在实现时不必指定::detail