繁体   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