在unordered_map中删除指向对象的指针

时间:2016-04-07 15:44:48

标签: c++

我正在尝试删除对unordered_map元素的引用。我负责的课程部分如下:

class Edge:
{
    public:
        Node* from;
        Node* to;
}

class Node:
{
    public:
        std::string name;
        bool to_delete;
}

class Graph:
{
    public:
        std::unordered_map<std::string, Node> nodes;
        std::vector<Edge> edges;
}

在我的主文件代码中,我正在做这样的事情:

    Node n("My node");
    graph.nodes.insert({n.name,n});
    edge.from = &graph.nodes[n.name];

    // Some other stuff

    for(auto& edge : graph.edges)
    {
        if(edge.from->to_delete)
        {
            graph->nodes->erase(edge.from->name);
            delete edge.from;
            edge.from = NULL;
        }
        if(edge.to->to_delete)
        {
            graph->nodes->erase(edge.to->name);
            delete edge.to;
            edge.to = NULL;
        }

        if(edge->from && edge->to)
            DoSomethingWithNodes(edge->from, edge->to);
        else
            removeEdge(edge);
    }

目前我正在删除基于此answer的指针,但我在delete上遇到了细分错误。在同一个答案中,还建议使用smart pointers。我不确定在这里使用shared_ptr。我在这里有选择,多个边将指向一个节点对象,但是当我从图的unordered_map中获取erase节点时会发生什么。如果它指向那里,我会在最后的if / else条件下得到错误吗?我不完全理解这一点。

修改

假设我想在删除之前显示节点的名称。所以我会有类似的东西:

for(auto& edge : graph.edges)
{
    if(edge.from->to_delete)
    {
        printf("Node to delete: %s",edge.from->name.c_str());
        graph->nodes->erase(edge.from->name);
        edge.from = nullptr;
    }
    if(edge.to->to_delete)
    {
        printf("Node to delete: %s",edge.to->name.c_str());
        graph->nodes->erase(edge.to->name);
        edge.to = nullptr;
    }

    if(edge->from && edge->to)
        DoSomethingWithNodes(edge->from, edge->to);
}

现在,没有针对空指针的保护,因为我经历过edge.from->to_delete以某种方式,有时会返回true。我所尝试的是如果条件改变:

if(edge.from && edge.from->to_delete)

但它根本没有帮助。

1 个答案:

答案 0 :(得分:1)

  

目前我正在根据此答案删除指针

您不理解该答案 - 您只能deletenew创建的对象并且您控制它们的所有权,您的案例中的对象在您存储时由std::unordered_map管理按值,而不是指针。因此,在这种情况下,您无法在这些对象上调用delete,并且调用std::unordered_map::erase()就足以删除对象。

示例:

std::unordered_map<std::string,Someclass> mymap;
mymap.insert( std::make_pair( "foobar", Someclass() ); // adding object by value
...
mymap.erase( "foobar" ); // object managed by map and will be deleted

或需要致电删除时:

std::unordered_map<std::string,Someclass *> mymap;
mymap.insert( std::make_pair( "foobar", new Someclass() ); // adding object by pointer
...
auto f = mymap.find( "foobar" );
if( f != mymap.end() ) {
    delete f->second; // you need to delete object that you created by new before
    mymap.erase( f );
}