2011-11-03 42 views
2

我目前正在编写一些必须是可移植的代码。为此,我使用pimpl成语,因为我认为它从API中清楚地分离了实际的实现。 总而言之,如果实现不共享代码(即跨实现共享的一些泛型函数),则pimpl习惯用法只起作用。C++:跨pimpl实现的共享代码

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

那么你会建议在不同的pimpls上共享代码有哪些选择?我想到了pimpl本身的一个抽象接口类,所以实际的API仍然是完全分离的,但这似乎也是一个奇怪的想法。 PS:我不想讨论pimpl或抽象接口是否更好。从API的角度来看,我决定和pimpl一起去,我想坚持下去。

回答

1

VTK有很好的PIMPL设计。核实!

Here is the VTK coding standard.

+0

谢谢,听起来很不错! – moka

+0

该标准看起来好像是在十五年前写的:遗憾的是错过了C++以来发生的所有事情。 –

+0

@NicolaMusatti:这可能是真的。你应该检查VTK支持的编译器。这个标准非常重要,我对改进非常满意,但另一方面,我们应该研究真正的编译器。 :) – Naszta

2

可以共享代码只是移动到一个新的独立的类,命名空间或模块。

1

即使实现包含pimpls,您的类模型也可以包含抽象类。这两个是正交的。

但是,如果您将所有私有方法放入您的pimpl中,则可能会有几个箍环跳过。调用一个实例方法,无论在哪里定义,都需要一个指向实例的指针。您可以将实例指针作为参数提供给pimpl方法,或隐式地提供给外部类中的私有方法。

另一种选择是通过组合而不是继承进行分享,这有其自身的优势。

+0

是的,我想过通过组合来分享.-我认为这甚至可能使得依赖更加明确,这对于想要触摸移植的实际代码的人来说是非常好的。当然有些事要考虑! – moka

0

如果您实现PIMPL的细节是可重复使用的,那么您应该不会对将它们公开发表感到不满。重点是保持界面清洁。

虽然有时你想分享那些真的不应该在外部使用的助手。在这一点上,清楚记录,不应该重复使用的东西是你正在努力解决的真正问题。我喜欢为此使用细节/私人标题。

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

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

thingajig.h 
thingajig_priv.h 
thingajig_detail.h 

它不会让人们用霰弹枪走出你的客厅。我会说你不应该尝试。不过,真的很难无意中拉入这个共享代码。

然后在你的cpp文件中重用代码,你可以在anon命名空间中包含详细的命名空间。

namespace some_public_ns { 
namespace { 
    using namespace detail; 
}} 

这可以让你保持混乱你的命名空间,但其实施时指定::detail保持。

+0

嗨,我实际上把所有的pimpl类放在一个详细的命名空间中,就是因为这个原因(即只有一个以Window开头的类在实际的命名空间中,而不是另一个WindowImpl)。我想我现在有一些想法可以解决我的问题,无论是使用免费函数还是使用合成函数以及某些可供小妞使用的帮助程序结构。谢谢! – moka