2012-03-28 60 views
1

我有一段時間的模板包裝C庫FILE *。這是一個相當經典的FILE *包裝類的共享指針實現。使用我自己的自定義共享指針的原因是爲某些C庫FILE *免費函數提供了免費函數替換,以便允許我替代使用FILE *的舊代碼。需要幫助解決運行時多態性使用模板

,我有實現使用的內包裝材料,保證當它被刪除,所擁有的FILE *關閉。 RAII。

但是,我需要創建一個類似的系統來處理這種情況,我希望底層的FILE *被沖刷掉,而不是在最後一個FILE *持有者被銷燬時關閉。也就是說,我有一個原始保證關閉類型的FILE *,但希望將FILE *的一個無主副本分發給另一個對象,該對象將保證當最後一個實例被銷燬時,它會刷新&截斷FILE *而不是關閉它,因此我將底層FILE *留在打開狀態,但將流的內容刷新到磁盤(並且文件大小僅反映有效內容)。

我已經爲編譯時多態性解決了這個問題。但我需要一些方法來提供運行時多態性,而且我真的不想在這種情況下放置另一層間接指向(即,如果我使用多態指針指向自動關閉或自動刷新文件*包裝,我會是金 - 但我真的想保持現在的深度,並隱藏定製共享指針實現中的多態性)。

基本上,如果我有一個:

template <class WrapperT> 
class FilePointerT 
{ 
public: 
    // omitted: create, destroy, manipulate the underlying wrappered FILE* 
private: 
    WrapperT * m_pFileWrapper; 
    ReferenceCount m_rc; 
} 

顯然,噸細節省略。只要說這些對象中的最後一個被刪除,它就會刪除最後一個m_pFileWrapper(實際上,如果我正在重寫這段代碼,我可能會使用boost :: shared_ptr)。

無論如何,這裏真正的問題是我如何擁有一個FilePointerT WrapperT >其WrapperT可以改變,但可以在代碼中使用,就好像它們都是一樣的(畢竟,它們是由於WrapperT實施具有零上FilePointerT的結構和接口(本質上是平普爾)的影響。

我能聲明都不可能持有任何FilePointerT <WrapperT>任何WrapperT?

或者說,如何我可以更改FilePointerT的定義以便允許我提供特定的WrapperT嗎?

回答

0

對於它的價值,我最後做的是在包裝件嵌入到一名爲FilePointer類,而不是使其成爲其類型的一部分。

class FilePointer 
{ 
public: 
    // create using a file wrapper (which will handle policy issues) 
    FilePointer(FileWrapper * pfw) : m_pFileWrapper(pfw) { } 

protected: 
    FileWrapper * m_pFileWrapper; // wrapper has close/flush policy 
    ReferenceCount m_references; // reference count 
}; 

然後將文件指針正好代表了實際工作的包裝,以及包裝實施必要的政策,並且可以編寫代碼消耗一名爲FilePointer(S)。

顯然還有其他的方法可以做到這一點,但這就是我的目標。

3

難道你不能簡單地使用std::shared_ptr<FILE *, deleter_function>?爲免費功能提供普通的重載,沒有有趣的模板malarky。

+0

尋找此解決方案...... – Mordachai 2012-03-28 14:29:40

2

您可以使用type erasure治療FilePointerT的所有版本透明。正如上面的海報所提到的,我也會採用shared_ptr方法,實際上,刪除器甚至不是shared_ptr簽名的一部分,因此您可以在保持類型不變的情況下更改刪除器。

+0

+1類型擦除,這是''shared_ptr'解決方案如何以及爲什麼工作,畢竟。 – 2012-03-28 14:34:50