C++ Vector 内容正在被删除?

C++ Vector content is being deleted?

我一直在尝试根据 https://www.youtube.com/watch?v=V_TulH374hw

创建有向图
class Digraph {
public:
    Digraph();

    void addNode(Node);
    void addEdge(Edge);

    void print();

private:
    //This is a vector which contains a node source and a vector of node destinations
    vector< tuple< Node, vector<Node>>> nodes;
};

但是在我添加了 2 个节点和一个边之后,带有目的地的向量似乎被清空了

void Digraph::addEdge(Edge e){
   Node src = e.getSrc();
   Node dest = e.getDest();

   for(auto node : nodes){
       if(get<0>(node).getName() == src.getName()){
           get<1>(node).push_back(dest);
           //cout << "added conection " << get<0>(node).getName() << " -> " << get<1>(node).back().getName() << " now "  << get<0>(node).getName() << " has " << get<1>(node).size() << " destinations" <<"\n";
           return;
       }
   }

   cout << "node " << src.getName() << " does not exist \n";
   return;
}

void Digraph::print(){
   for(auto node : nodes){
       get<0>(node).print();
       cout << " has " << get<1>(node).size() << " destinations";
       cout << "\n";
       for(auto destination : get<1>(node)){
           cout << "\t->";
           destination.print();
           cout << "\n";
       }
}

}

在main.cpp中我添加了节点和边

graph.addNode(NY);
graph.addNode(CHICAGO);

graph.addEdge(road);
graph.print();

它最终成功添加了边缘,但是当它打印最终结果时它无法识别刚刚添加的边缘

added conection NY -> Chicago now NY has 1 destinations
NY has 0 destinations
Chicago has 0 destinations

当尝试使用更多节点和边时,我意识到它永远不会添加超过一个边,也许这与我定义 class 的方式有关?向量是不是选择?

你的for循环中的auto需要引用(auto&),在代码后面我会告诉你原因。

void Digraph::addEdge(Edge e){
   Node src = e.getSrc();
   Node dest = e.getDest();
   // use references here
   for(auto& node : nodes){
       if(get<0>(node).getName() == src.getName()){
           // now this modifies the original, not a copy
           get<1>(node).push_back(dest);
           //cout << "added conection " << get<0>(node).getName() << " -> " << get<1>(node).back().getName() << " now "  << get<0>(node).getName() << " has " << get<1>(node).size() << " destinations" <<"\n";
           return;
       }
   }

   cout << "node " << src.getName() << " does not exist \n";
   return;
}

这个函数的全部意义在于以某种方式改变节点。如果您使用 for (auto node : nodes) 遍历它们,您将获得每个节点的副本。和Node node : nodes一样,auto没有区别。然后你在这个副本上调用 push_back,它会在下一个循环迭代出现时立即被销毁。

实际上,您的原始文件完全保持不变,因为您只复制了它的成员节点,而不是 references

如果你像我一样在此处使用引用,你将引用 nodes 向量中的每个节点,并修改引用,这会修改原始文件。