2011-11-03 57 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