簡體   English   中英

將指向對象的指針存儲在多個容器中

[英]Store pointers to objects in multiple containers

為了提出我的問題,讓我們假設我有一組指針(相同類型)

                                {p1, p2, ..., pn} 

我想將它們存儲在多個容器中,因為我需要不同的訪問策略來訪問它們。 假設我要將它們存儲在兩個容器中,即鏈表和哈希表。 對於鏈表,我有順序,對於哈希表,我可以快速訪問。 現在的問題是,如果我從一個容器中刪除了一個指針,則需要記住要從另一個容器中刪除。 這使得代碼難以維護。 所以問題是,還有其他模式或數據結構可以管理這種情況嗎? 智能指針在這里有幫助嗎?

如果我理解正確,則希望鏈接容器,以便從一個容器中刪除所有容器。 我認為這不可能直接實現。 可能的解決方案:

  • 重新設計整個對象體系結構,因此指針不在很多容器中。
  • 使用Boost Multi-index Containers庫可在一個容器中實現所需的所有功能。
  • 使用地圖鍵而不是直接指針來跟蹤對象,並將指針本身保留在一張地圖中。
  • 使用std::weak_ptr以便您可以檢查項目是否已在其他位置刪除,並在使用時將其轉換為std::shared_ptr (您需要一個容器來擁有“主” std::shared_ptr ,以便在不使用時保持對象周圍)
  • 創建函數/方法/類以刪除知道所有容器的對象,因此當所有刪除都在一個位置時,您不會忘記它。

為什么不創建同時包含std::liststd::unordred_map並提供訪問函數和刪除函數,您可以使用list線性訪問它們,並使用unordred_map隨機訪問它們,並且刪除將同時從兩個容器中刪除,並且插入將同時插入到這兩個容器中。 (一種包裝類:P)

您也可以考慮使用std::map ,並為其提供比較功能 ,該功能始終將數據結構按所需方式排序,並且還可以使用log N訪問時間來隨機訪問元素。

通常,請嘗試隔離此邏輯以使事情更容易支持。 一些帶有安全公共接口的小類(對不起,我沒有編譯它,它只是一個偽代碼)。

template<class Id, Ptr>
class Store
{
public:
   void add(Id id, Ptr ptr)
   {
      m_ptrs.insert(ptr);
      m_ptrById.insert(std::make_pair(id, ptr));
   }

   void remove(Ptr ptr)
   {
      // remove in sync as well
   }

private:
   std::list<Ptr> m_ptrs;
   std::map<Id, Ptr> m_ptrById;
};

然后使用Store保持指針同步。

如果我正確地理解了您的問題,那么您對內存管理(新/刪除問題)的關注就更少了,而對哪個元素有效或不正確的實際“記賬”更加關注。

因此,我正在考慮使用“參考計數器”包裝每個點

 template< class Point >
 class BookKeeping {
 public:
     enum { LIST_REF = 0x01,
            HASH_REF = 0x02 };
     BookKeeping( const Point& p ): m_p(p), m_refCout( 0x3 ) {} // assume object created in both containers
     bool isValid() const { return m_refCount == 0x3; } // not "freed" from any container
     void remove( unsigned int from ) { m_refCount = m_refCount & ! from ; }
 private:
     Point m_p;
     unsigned int m_refCount;
 };

請參閱這個類似問題的答案(到目前為止,唯一的答案)。 在這種情況下,建議使用deque ,而不是list ,因為OP只想在序列的末尾插入/刪除。

無論如何,您可能更喜歡使用Boost Multi-index Containers庫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM