2015-07-19 45 views
4

Effective Modern C++(第136頁)使用以下示例來激勵std::weak_ptr。高速緩存被定義爲一個無序映射,其中有指向對象的弱指針作爲值。只要這個緩存的客戶請求一個對象(通過鍵),就會查找相應的弱指針並在其上調用lock()。如果得到的std::shared_ptr不是null,則返回。否則,該對象將從外部數據庫重新加載,然後輸入緩存並返回std::shared_ptr我理解了Scott Meyers的std :: weak_ptr示例的正確點嗎?

現在的問題:人們可能會認爲有可能不使用std::weak_ptr來實現這一點,而是將強共享指針存儲爲緩存值。如果一個強指針的use_count()等於1,那意味着所有客戶端的指針都被銷燬了。這個例子中使用std::weak_ptr的整點是否允許我們通過實際刪除對象來節省內存?

+0

'use_count'永遠不會是一個:當你插入新的對象,你有一個副本在緩存中,一個被返回,所以使用計數是兩個。誰會回去清理緩存? –

+0

@KerrekSB我認爲你在談論兩件不同的事情。首先,當用戶在他的副本上調用reset()時,計數將再次變爲1。當他繼續並再次從緩存中請求對象時,'use_count()'將成爲一個。其次,沒有人會去清理現金,這意味着實際的對象不會被刪除。但這僅僅意味着你對我的問題回答「是」,對嗎? – AlwaysLearning

回答

5

「使用std :: weak_ptr的這個例子的整個點是否允許我們通過實際刪除對象來節省內存?」

是的。否則,緩存將無限期地分配指向的資源。控制塊所需的空間(如果單獨分配)通常遠小於可能需要緩存的資源類型(例如紋理,網格數據,甚至是本地化的字符串)。

雖然可以使用原子實現相同的功能並檢查引用計數爲1,但這需要定製句柄實現。 std::weak_ptrstd::shared_ptr使整個事情少得多原型的考驗。

+0

出現一個彈出窗口,說我可以將此答案標記爲已接受,但我無法找到該按鈕來執行此操作... – AlwaysLearning

+0

@MeirGoldenberg如果將鼠標懸停在投票計數器下方的區域上方,則應出現勾選的複選標記。 – defube

+2

可能值得一提的是,'weak_ptr :: lock()'是一個原子操作,但是檢查use_count()== 1'然後作用於該信息不是原子操作。例如,在緩存中檢查use_count()== 1'之後,但在刪除數據之前,另一個線程可能會檢查緩存並說:我想要引用該數據!因此將'use_count()'碰撞到2.第一個線程然後不必要地從緩存中刪除'shared_ptr'。 'weak_ptr's和'weak_ptr :: lock()'不會發生這種情況。 –