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
向量中的每个节点,并修改引用,这会修改原始文件。
我一直在尝试根据 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
向量中的每个节点,并修改引用,这会修改原始文件。