2013-03-18 61 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