2010-07-11 101 views
5

所以我一直在思考PIMPL和堆棧分配。我一直在寫圖書館,並決定使用PIMPL來隱藏課程的私人成員。這意味着我會有一個這樣的聲明PIMPL和堆棧分配

class Foo { 
private: 
    class Handle; 
    std::tr1::shared_ptr<Handle> handle; 
public: 
    Foo(); 
}; 

這是非常簡單的。但隨後在構造函數中完成此

Foo::Foo() : handle(new Handle()) {} 

因此,當有人使用我的圖書館在棧上創建了一個富,他們基本上是做一個堆分配反正。這是在使用PIMPL時必須權衡的折衷?我想在構造函數旁邊發佈一個警告文件:「警告:這會導致堆分配」或其他。

我的另一個想法是將所有暴露於實現的類作爲純虛擬接口和一大堆靜態工廠方法返回智能指針。這也意味着堆分配,但沒有技巧。

任何想法或建議?我是否過度體貼使用我的圖書館的程序員?

+1

這樣的警告的問題是大量的操作導致堆分配。創建一個'std :: vector'也可以。或者調整一個。權衡隱藏類的內部是多麼重要,而避免堆分配的額外表現。 – jalf 2010-07-11 06:51:38

回答

4

這是在使用PIMPL時必須權衡的權衡嗎?

有效,是的,雖然有技術,如那些由香草薩特在"The Fast Pimpl Idiom,"討論了可用於消除或加快堆分配,以更大的複雜性爲代價。

我想釋放構造函數旁邊的警告文檔:「警告:這會導致堆分配」或somesuch。

只有在必要時才這樣做(即只有當您的用戶會對您的班級執行堆分配感到驚訝時)。許多類執行堆分配,包括C++標準庫中的許多類(例如所有容器)。

我是否過度體貼使用我的圖書館的程序員?

可能:-)。除非你對班級有很高的性能要求,或者你希望班級的例子經常被創建和銷燬,否則我不會太擔心。當然,如果你有明顯的性能要求,pimpl可能不是一個好的選擇。

+0

很酷,謝謝。無論如何,我會看起來像Fast Pimpl,因爲它看起來很有趣。 – Anthony 2010-07-11 02:42:31

4

所以當有人使用我的庫在堆棧上創建一個Foo時,它們實質上是在做一個堆分配。這是在使用PIMPL時必須權衡的折衷?

是的。

我想釋放構造函數旁邊的警告文檔:「警告:這會導致堆分配」或somesuch。

我會考慮過度激烈的評論:)如果你的課是如此性能的關鍵,也許你應該避免PIMPL成語。如果你代表一個號碼,這可能是值得關注的,值得注意。如果你隱藏了實現一個數據庫連接的,不值得評論:)

我的另一個想法是有其暴露於實施爲純虛擬接口和一大堆的靜態工廠方法返回的所有類聰明的指針。這也意味着堆分配,但沒有技巧。

是的,這對用戶來說更加明顯,但是可能再也不值得關注自己了。

有什麼想法或建議嗎?我是否過度體貼使用我的圖書館的程序員?

這是一個折衷,但如果你的班級足夠複雜以從pimpl習語中獲得真正的收益,那麼你可能會認爲堆分配是可以的。如果我正在使用你的庫,它可能不會涉及我。

+0

很酷,謝謝。我會繼續做'我在幹什麼'。 – Anthony 2010-07-11 02:44:40