我目前正在编写一些必须可移植的代码。为此我使用了pimpl习语,因为我认为它从API中干净地分离了实际的实现。 无论如何,如果实现不共享代码(即一些跨实现共享的通用函数),那么pimpl习惯用法只会非常有用。
另一种选择是我猜的抽象接口.-无论如何,因为我在整个项目中使用pimpl,我真的不认为将它与抽象接口混合(在API级别上)。
那么您建议在不同的pimpls之间共享代码的选项是什么?我想到了pimpl本身的一个抽象接口类,所以实际的API仍然干净利落地分开,但这似乎也是一个奇怪的想法。
PS:我不想讨论pimpl或抽象接口是否更好。从API的角度来看,我决定选择pimpl,我想坚持下去。
答案 0 :(得分:2)
您只需将共享代码移动到新的独立类,命名空间或模块即可。
答案 1 :(得分:1)
VTK具有很好的PIMPL设计。检查一下!
答案 2 :(得分:1)
即使实现包含pimpl,您的类模型也可以包含抽象类。两者是正交的。
但是,如果您将所有私有方法都放入pimpl,那么可以通过几个环节来跳过。无论在何处定义,调用实例方法都需要指向实例的指针。您可以将实例指针作为pimpl方法的参数提供,或者隐式地提供在外部类中的私有方法中。
另一种选择是通过组合而不是继承来分享,这有其自身的优势。
答案 3 :(得分:0)
如果你实施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文件中,您可以在anon名称空间中包含detail命名空间。
namespace some_public_ns {
namespace {
using namespace detail;
}}
这使您可以在命名空间之外保持混乱,但在实施时不必指定::detail
。