2016-08-30 55 views
0

我有一個類通過它暴露的接口增加功能:接口功能讓右值指針初始化的shared_ptr

void AddObject(Object *o); 

類裏面我保持set<shared_ptr<Object>>的對象。 由於我將從接收到的指針創建shared_ptr,我認爲只將函數參數限制爲右值指針,以確保用戶不會刪除我使用的指針。所以,我會改變函數聲明:

void AddObject(Object* &&o); 

這樣一個典型的使用將是:

AddObject(new Object()) 

防止用戶不小心刪除指針我抱。 我不想在界面中使用shared_ptr,因爲用戶不熟悉shared_ptr。 你認爲我的建議是個好主意嗎?

+0

「std :: unique_ptr」有什麼問題? – AndyG

+0

那麼同樣的問題適用,如果我使用unique_ptr而不是 –

+0

我認爲'unique_ptr'使它在界面中更加明顯。另外,'move'語義已經與傳遞它們並行,所以'std :: move'一個'unique_ptr'是很自然的,但對於'std :: move'原始指針來說真的很奇怪。 – AndyG

回答

0

我認爲這是一個壞主意。我確信有一個原因,爲什麼shared_ptr c-tor獲取原始指針被標記爲顯式而不是使用r值。在我看來,最好教會用戶一次關於智能指針,或者至少教導他們如何使用make_shared/make_unique(它們更安全,並且在make_shared的情況下更高效,順便說一下)。

順便說一句,爲什麼shared_ptr而不是unique_ptr

另外,爲什麼set?即使你想確保你只保留一次指針,並且每次搜索vector在代碼中看起來都不夠自然,我沒有看到有理由保持指針的排序而不是使用unordered_set

0

首先,這種方法不會阻止用戶刪除指針。考慮這個例子

auto obj = new Object(); 
    AddObject(std::move(obj)); 
    delete obj; 

其次,調用newshared_ptr創作應儘可能少之間步驟的數量。如果在AddObject之內發生任何事情,它可以創建shared_ptr之前,該對象將永遠不會被刪除。

如果AddObject()有更多參數,則同樣適用。如果構建這些失敗,你會泄漏內存。

void AddObject(Object* &&o, SomeOtherObject* x); 

    AddObject(new Object(), xx()); // if xx() throws, memory leak will occur 

理想情況下,你會「包裝」對象創建爲shared_ptr建設:

void AddObject(std::shared_ptr<Object> o); 

    AddObject(std::make_shared<Object>()); 
+0

你的第一個例子確實顯示了用戶如何刪除提供的指針,但它非常明確,只有惡意用戶纔會這樣做。 –

0

下列方法之一可以解決你的問題。

  1. 您可能會附加更多關於AddObject的評論,告訴用戶刪除他們添加的指針是不被允許的。這已經足夠了。
  2. 或者,你也可以讓Object繼承自一個基類,該基類有一個私有的析構函數和一個名爲destroyByOwner的方法。