2010-02-25 57 views
3

對於某些類的靜態C++庫,我想爲庫的用戶和庫本身提供不同的接口。爲類/信息隱藏創建內部和外部接口

一個例子:

class Algorithm { 

    public: 

    // method for the user of the library 
    void compute(const Data& data, Result& result) const; 


    // method that I use only from other classes of the library 
    // that I would like to hide from the external interface 
    void setSecretParam(double aParam); 

    private: 

    double m_Param; 
} 

我的第一次嘗試是創建外部接口作爲ABC:

class Algorithm { 

    public: 

    // factory method that creates instances of AlgorithmPrivate 
    static Algorithm* create(); 

    virtual void compute(const Data& data, Result& result) const = 0; 
} 

class AlgorithmPrivate : public Algorithm { 

    public: 

    void compute(const Data& data, Result& result) const; 

    void setSecretParam(double aParam); 

    private: 

    double m_Param; 
} 

優點:

  • 算法的用戶無法看到內部接口

缺點:

  • 用戶必須使用工廠方法創建實例
  • 我不得不垂頭喪氣算法對AlgorithmPrivate當我想從庫中訪問機密參數。

我希望你明白我想達到的目標,我期待着任何建議。

+1

如果不加破壞方法需要算法的虛擬析構函數。但我沒有看到你的問題。 – Totonga 2010-02-25 08:46:26

+0

爲了簡單起見,我省略了構造函數和析構函數,當然算法需要一個虛擬析構函數。問題在於是否有比我更優雅的解決方案,可以將一個班級的成員打開到其他班級,同時將他們從「外部」隱藏起來。 – Stephan 2010-02-25 11:20:34

回答

3

創建最簡單的方法可能是讓setSecretParam()private,並進行以下一個friendAlgorithm的:

void setSecretParam(Algorithm& algorithm, double aParam) 
{ 
    void setSecretParam(double aParam); 
} 
+1

感謝您的回答,我看到使用「朋友」確實做我想要的。但ABC方法甚至隱藏了祕密參數的存在,隱藏程度更高。我希望有一個解決方案,儘可能少地向外部展示,同時儘可能多地向圖書館內部展示。也許使用朋友是C++最好的解決方案。 – Stephan 2010-02-25 11:36:47

+1

如果要隱藏函數的存在,可以將它隱藏在疙瘩中(http://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B)。 – sbi 2010-02-25 12:15:51

+0

你是對的,我一直在考慮使用pimpl,我認爲這是目前爲止最好的方法,因爲編譯器可以優化getImpl()訪問並且不需要動態轉換。謝謝! – Stephan 2010-02-26 09:04:42

1

替換遺傳的「常見嫌疑人」是Bridge pattern。您可以定義從抽象類AlgorithmImp派生的「Imps」的層次結構,並僅在庫標頭中公開適當的算法。然後算法的一個實例可以爲

ConcreteAlgorithm ca1(SomeParam, new LibraryUserAlgorithm()); 
ConcreteAlgorithm ca2(SomeParam, new InternalAlgorithm()); 
+0

據我所見,這種方法與使用ABC非常相似。要使用「內部接口」,我必須通過一些公共訪問器來獲得實現,並且可以管理其參數。這非常類似於向下執行。使用ABC的好處在於,甚至沒有外部世界可以看到的「getImpl()」方法。感謝您的建議! – Stephan 2010-02-25 11:43:07