2011-11-20 46 views
6

我有一個resource_manager類,在內部維護std::vector<boost::shared_ptr<resource> >resource_managerresource的朋友。我希望resource只能由resource_manager創建/刪除,所以我將它的構造函數設置爲私有的(工作正常)。如何從shared_ptr調用私有析構函數?

但是,如果我將析構函數設爲私有的,代碼將不會編譯,因爲析構函數被boost::shared_ptr調用,它不是resource的朋友。我想執行「不要刪除客戶端」規則,只從resource_manager只返回const resource*,但不知何故,我不滿意這種方法提供的安全性(如果客戶端以某種方式發生在非const的指針? )

除了明顯的不使用shared_ptr的解決方案之外,您是否有任何解決方法/更好的解決方案來解決我的問題?

+0

的唯一途徑「客戶端跨一個指向非const不知何故發生了」,他們能做到這一點是,如果他們使用const_cast進行投射。從「安全性」的角度來看,原始指針和shared_ptr之間沒有區別,不同之處在於生命週期管理,我不確定在沒有shared_ptr的情況下如何處理。 – ronag

+4

'const resource *'並不意味着你不能刪除它。 – UncleBens

+0

@UncleBens:不?我認爲編譯器不應該允許你在const上調用一個非const函數!我錯了嗎?或者這個規則不適用於析構函數? –

回答

11

您可以將自定義刪除器傳遞給共享指針。所以只需要創建一個刪除器仿函數或函數(由你),這又是你的類的friend

class Secret 
{ 
    ~Secret() { } 
    friend class SecretDeleter; 
    friend void SecretDelFunc(Secret *); 
}; 

class SecretDeleter 
{ 
public: 
    void operator()(Secret * p) { delete p; } 
}; 

void SecretDelFunc(Secret * p) { delete p; } 

std::shared_ptr<Secret> sp1(new Secret, SecretDeleter()); 
std::shared_ptr<Secret> sp2(new Secret, SecretDelFunc); 
+0

時,它似乎沒有工作爲什麼你總是比我有更快的想法?不要那麼做! :( – Xeo

+0

@Xeo:最好挑選一塊不同的蛋糕 - 我的眼睛緊緊地盯着'shared_ptr' !--) –

+1

順便說一句,你應該實例化'SecretDeleter'。 – Xeo

1

也許宣佈shared_ptr<resource>爲朋友? shared_ptr不調用構造函數,並且只應在您的資源管理器在所有客戶端銷燬其shared_ptrs之前釋放指針時纔會銷燬。這不會允許客戶打破保護,但會允許客戶保持資源與resource_manager的「意願」保持一致。

+0

當我嘗試 –

相關問題