2013-03-18 80 views
0

我有一个属于管理构造的std::list<Value>,每当调用工厂方法时都会提供Value *指针。当需要销毁Value时,这些指针会传回给管理器。但是,我不确定如何最好地使用这些指针来查找和删除/删除元素。从std :: list中删除<Value>使用指向Value的原始指针?

class ValueManager{ 
public: 

    Value * createValue(ValueDef & def) { 
     m_valueList.push_back(Value(def)); 
     return &m_valueList.back(); 
    } 

    void destroyValue(Value * target) { 

     // Mystery! 
     // How does one remove/erase a list element 
     // with only a pointer to it's value? 

    } 

private: 

    std::list<Value> m_valueList; 

}; 

两个::erase::remove似乎生病适合的任务,一个使用一个迭代器,而不是一个指针,而后者则采用的全部价值,不能因为做了,在这种情况下,不存在可接受== Values之间的比较方法,只有指针可以可靠地用于查找目标。

我的问题是最有效的实施destroyValue()可以承担什么?

+2

你要返回的地址是* iterator *,而不是值。使用迭代器*本身*作为返回值(除了真正的'std :: list <>'以外,不要试试这个)。 – WhozCraig 2013-03-18 00:49:55

+0

@WhozCraig - 不知道我跟着,它返回存储为列表中最后一个元素的元素的地址,对不对?是的,我使用一个列表,因为它不重新分配节点,使地址无效到内存。 – 2013-03-18 01:10:17

+0

你应该返回'std :: list :: iterator'。在接收端使用它的语法与指针相同('* x'将使用迭代器的解引用操作符来获取底层值)。访问地址将需要小费('&(* x)'),但仍然可行。然而,现在你可以使用该迭代器作为包含'std :: list '的基于迭代器的操作的直接输入,例如'erase()'等。 – WhozCraig 2013-03-18 01:14:12

回答

3

简单:停止返回原始指针,并开始返回迭代器。然后,想要销毁它的用户将在创建时接收到的值,就像现在一样。取消引用仍然可以像处理原始指针一样工作。但擦除也会起作用,并且效率很高。

+0

+1没有大的冲击I agree = P – WhozCraig 2013-03-18 00:51:17

+0

我想避免迭代器,因为它们在使用它的代码中需要冗长的'std :: list :: iterator'声明。另外,它暴露了迭代器访问未明确返回的其他元素的能力,例如使用'++',这会导致事情在完全使用时变得不合适。有没有办法只使用指针? – 2013-03-18 01:15:49

+0

所以做一个typedef,就像'ValueIter'。这样它只需要输入2个字符(vs'Value *')。如果你真的需要阻止“移动”返回的迭代器,只需创建自己的类类型并返回它,并让它包含一个迭代器并实现'operator *'来支持解引用。 – 2013-03-18 03:05:48