【发布时间】:2023-03-26 01:08:02
【问题描述】:
我正在尝试为有向图中的节点创建一个类(我对它们了解不多,如果我搞砸了任何术语,请原谅)。 每当我将指向 n2 的指针添加到 n1 的 outNodes 向量时,我希望将指向 n1 的指针添加到 n2 的 inNodes 向量。我希望这是有道理的,这是我的代码。
#include <iostream>
#include <vector>
class Node {
private:
static int nextId;
int id;
std::vector<Node*> ptr_outNodes;
std::vector<Node*> ptr_inNodes;
public:
Node() {
id = nextId++;
}
int getId() {
return id;
}
void setInNodes(Node n) {
ptr_inNodes.push_back(&n);
}
void setOutNodes(Node n) {
ptr_outNodes.push_back(&n);
n.setInNodes(*this);
}
std::vector<Node*> getOutNodes() {
return ptr_outNodes;
}
std::vector<Node*> getInNodes() {
return ptr_inNodes;
}
};
int Node::nextId = 0;
int main() {
Node n1;
Node n2;
n1.setOutNodes(n2);
std::cout << n2.getInNodes().size();
return 0;
}
如您所见,我已将其设置为返回 n2 的 inNodes 的大小。当我运行程序时,我看到它的大小为 0。如果我在 setInNodes 方法中打印出大小,我得到的结果 1 对我来说很奇怪。另外,如果我将主要功能更改为:
int main() {
Node n1;
Node n2;
n1.setOutNodes(n2);
n2.setInNodes(n1);
std::cout << n2.getInNodes().size();
return 0;
}
我得到结果 1。添加该行表明该函数正在工作,所以我相信当我从 setOutNodes() 调用 setInNodes() 时出现问题。过去半小时我一直在盯着这个,所以如果有人可以帮助我,那就太好了,谢谢!
【问题讨论】:
-
setInNodes和setOutNodes都推送了传值的函数参数的地址,所以是原始的副本,在函数结束时超出范围。这是未定义的行为。您的两个get*函数也都按值返回向量,因此是另一个副本。这不一定是问题,但您确实需要注意这一点,以防您尝试getOutNodes().push_back(whatever)之类的东西并想知道为什么原始向量没有改变。 -
@RetiredNinja 那么我应该尝试将引用存储在向量中吗?
-
你应该做的是充分学习和理解:1)通过值传递参数与通过引用传递参数之间的区别,以及2)在自动和动态范围内声明的对象之间的区别。两者都是对象如何在 C++ 中工作的基本核心原则,必须完全理解这个主题。对这些核心主题的完整讨论不能用 Stackoverflow 上的一两句话来完全概括,而是每本 C++ 教科书中多个章节的主题,您可以在其中查找更多信息和详细解释。
-
void addInNode(Node* node)实际上&n获取堆栈上复制的节点结构的地址,这会给出危险的悬空指针。