设计模式,允许在C ++中从多个容器中有效删除元素

时间:2013-11-06 15:10:51

标签: c++ maps containers intrusive-containers

比如说,一个元素是从多个地图中引用的,例如元素的映射名称,元素的映射地址和元素的映射时间。现在,例如通过名称查找元素,现在希望从所有三个地图中删除它?

我想到了几种解决方案:

1)最直接的。在元素映射的名称中查找元素,然后搜索其他映射以查找其中的元素,然后删除所有三个元素条目。

2)在所有三个地图中存储弱指针。将共享指针存储在某处,甚至可能在元素本身中存储。在一个地图中找到元素后,删除该元素。当尝试从其他映射访问元素并意识到弱指针无法转换为共享指针时,请删除该条目。

3)使用侵入式地图。这具有以下优点:不需要搜索剩余的映射以找到那些中的元素。但是,由于对象存储在多个映射中,因此元素本身不能被侵入 - 相反,元素可能需要具有实现挂钩的成员。

4)其他人?

对此有一个非常干净的解决方案吗?我几次碰到这个问题......

一些想法。解决方案1通常是随着项目的增长而自然实现的解决方案。如果元素本身具有其他映射的关键信息,而其他容器是映射,则这可能是完全可以接受的。但是,如果缺少钥匙,或者如果容器是例如列表,它可能变得非常慢。解决方案2取决于弱指针的实现,也可能最终变得非常慢。解决方案3似乎最好,但可能有点复杂?

3 个答案:

答案 0 :(得分:0)

boost::multi_index专为此类案例设计。

答案 1 :(得分:0)

听起来你还没有决定什么是管理对象的生命周期 - 这是第一个。一旦你知道然后使用观察者模式。当要销毁对象时,对象的生命周期通知所有包裹指针的对象,然后销毁对象。

观察者可以实现这样的通用接口:

class ObjectLifetimeMgr
{
public:
    CauseObjDeletion()
    {
        /.. notify all observers ../
    }
private:
    list<IObserver*> observers;
};

class IObserver
{
public:
    virtual void ObjectDestroyed( Obj* );
};

class ConcreteObserver
{
public:
    void ObjectDestroyed( Obj* )
    {
        /.. delete Obj from map ../
    }
};

或者做一个非常可爱的工作你可以implement a c++ delegate,这可以让观察者从一个公共基类中释放出来,只是允许他们使用成员方法注册一个回调

答案 2 :(得分:0)

从未找到任何替换解决方案的内容1.我最终使用了shared_pointers并删除了对象中删除函数(例如DeleteFromMaps(bool map1, bool map2, bool map3))中的标记。然后来自例如map2的调用变为例如。

it->DeleteFromMaps(true,false,true);
erase(it);