2010-03-28 59 views
4

我有一組共享指針:移除*

std::set<boost::shared_ptr<T>> set; 

和指針:

T* p; 

我想有效刪除set的元素等於p,但是我不能對集合的任何成員或任何標準算法執行此操作,因爲T*是與boost::shared_ptr<T>完全不同的類型。

我能想到的一些方法是:

  • 莫名其妙地構建從不會採取有針對性的所有權內存(理想的解決方案指針一個新的shared_ptr,但我不能看到如何做到這一點)
  • 包裝/重新實施的shared_ptr,這樣我可以做到上面
  • 只是在做我自己的二進制搜索超過設定
+0

爲什麼你有這個原始的T指針呢? – dalle 2010-03-28 11:35:00

+1

爲什麼不呢?我常常在'Factory'類中找到自己的智能指針,並且只有外部的原始指針/引用。外部不需要知道我如何管理我的對象。 – 2010-03-28 14:02:30

回答

9

構建從T一個shared_ptr<T>null_deleter(見boost:::shared_ptr FAQ)。

struct null_deleter { 
    void operator()(void const *) const { } 
}; 

size_t remove_ptr_from_set(std::set<boost::shared_ptr<T>> &set, X* x) 
{ 
    shared_ptr<X> px(x, null_deleter()); 
    return set.erase(px); 
} 

這種方式的類型是兼容的,你不必擔心你的臨時shared_ptr刪除任何對象。

或者,正如其中一條評論所言,如果您可以將T更改爲從enable_shared_from_this繼承,那麼您可以從對象中獲得正確的共享ptr。

+0

啊,謝謝!這是我正在尋找的簡單解決方案。 – James 2010-03-28 11:22:35

+0

+1 Darn,即將發佈此。由於(錯誤的)想法,刪除器是'shared_ptr'類型的一部分,所以我首先駁回了它。 – 2010-03-28 11:24:17

+2

實際上有一個單獨的常見問題解答,用於在此答案中鏈接的FAQ中從'this'獲取'shared_ptr'。似乎有一個名爲'enable_shared_from_this'的類模板,當它繼承時,它爲'this'提供'weak_ptr'。請參閱http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/enable_shared_from_this.html。 – 2010-03-28 12:30:56

1

如果使用集中的原因是,你需要高效地找到類型T的指針,那麼顯而易見的答案不是使它成爲一組共享指針!相反,將該套件包裝在一個管理該套件包含的指針的生命週期的類中。

+0

組合繼承! – Eric 2010-03-28 11:02:32

+0

與其他選項相比,這似乎是一個大量的工作(這就是爲什麼我沒有列出它!):_only_時間我需要通過指針而不是shared_ptr查找是當我刪除對象(和對象可能會持續除非直到最後一個用戶的shared_ptr被銷燬),所以我不能盲目地將對象的使用期限與他們在容器中的存在關聯起來。 – James 2010-03-28 11:05:54

+0

@Eric - 不是。 'std :: set >'已經構圖,而不是繼承。尼爾建議撰寫正確的東西,而不是撰寫錯誤的東西。 – 2010-03-28 11:07:12

1

如果您希望集合擁有對象的所有權,您可以使用boost::ptr_set,如果您只想讓集合存儲對它們的引用,則可以使用boost::reference_wrapper。如果你在你的代碼的一個地方使用shared_ptr,你將不得不在所有地方使用它,否則將冒着可怕的崩潰(懸掛指針,已經被刪除的對象等)。 weak_ptr是一個例外,該指針指向由shared_ptr持有的對象,但不共享所有權。

+0

該集合是對象的一個​​所有者,但是其他用戶在從集合中移除後可能會保留,所以'boost :: ptr_set '不合適。 因爲這個原因,我也不能使用'reference_wrapper'或'weak_ptr',因爲在這兩種情況下,用戶可能會留下懸掛的引用。 – James 2010-03-28 11:12:55

+0

使用指針也有冒險指針的風險。爲什麼不能使用'shared_ptr'去除對象?爲什麼你在那裏引入一個正常的指針? – 2010-03-28 11:14:35

+0

我想從存儲的對象的成員函數中刪除,所以在堆棧的上方有一個指向該對象的shared_ptr,但我不希望在'this'指針是一應俱全。基本上我想這樣做:'removeFromSet(this)' – James 2010-03-28 11:20:01