0

例如,从多个映射中引用一个元素,例如映射名称到元素、映射地址到元素以及映射年龄到元素。现在,例如通过名称查找元素,现在希望从所有三个地图中删除它?

想到了几个解决方案:

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

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

3) 使用侵入式地图。这样做的好处是不需要搜索剩余的地图来找到其中的元素。但是,由于对象存储在多个映射中,因此不能使元素本身具有侵入性——相反,该元素可能需要有一个实现挂钩的成员。

4) 其他?

有没有一个非常干净的好解决方案?这个问题我碰到过好几次了...

一些想法。解决方案 1 通常会随着项目的发展而自然实施。如果元素本身有其他地图的关键信息,而其他容器都是地图,这大概是可以接受的。但是,如果缺少键,或者容器是例如列表,它可能会变得非常慢。解决方案 2 取决于弱指针的实现,并且最终也可能非常慢。解决方案 3 似乎最好,但可能有点复杂?

4

3 回答 3

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 ../
    }
};

或者为了做一个非常可爱的工作,你可以实现一个 c++ 委托,这将观察者从一个公共基类中解放出来,并简单地允许他们使用成员方法注册一个回调

于 2013-11-06T15:42:13.737 回答
0

从来没有找到任何东西来替代解决方案 1。我最终DeleteFromMaps(bool map1, bool map2, bool map3)在对象的删除函数(例如)中使用了 shared_pointers 和删除标志。来自例如 map2 的调用然后变为例如

it->DeleteFromMaps(true,false,true);
erase(it);
于 2014-05-28T20:24:53.603 回答
0

boost::multi_index是专门为这种情况设计的。

于 2013-11-06T15:32:28.510 回答