C++有向图节点类调用方法修改Vector后值未生效问题
问题根源
你的核心错误是方法参数使用了值传递,所有操作都作用在临时拷贝的对象上,完全没有修改你期望的原对象:
- 调用
setOutNodes(n2)时,会先拷贝n2生成一个方法内的临时局部对象,你往ptr_outNodes里存的是这个临时对象的地址,不仅不是原n2的地址,方法执行结束后临时对象销毁,这个指针还会变成野指针,后续访问直接触发未定义行为。 - 你在
setOutNodes内部调用n.setInNodes(*this)时,操作的也是n2的临时副本的ptr_inNodes,main函数里的原n2对象完全没有被修改,所以你外部打印原n2的inNodes大小自然是0,只有临时副本的inNodes大小是1,方法执行完副本就被销毁了。 - 你后来手动加的
n2.setInNodes(n1)能拿到size=1,只是因为这次你调用的是原n2对象的方法,所以原n2的ptr_inNodes确实加了1个元素,但里面存的是n1的临时拷贝的地址,依然是野指针,后续访问指针指向的内容一定会出问题。
修复方案
把两个方法的参数改成引用传递,直接操作原对象即可,同时建议把方法名改成更符合功能的addOutNode、addInNode,避免语义歧义:
#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() const { // 加const更符合C++编码规范 return id; } // 参数改为引用,直接操作原对象 void addInNode(Node& n) { ptr_inNodes.push_back(&n); } void addOutNode(Node& n) { ptr_outNodes.push_back(&n); n.addInNode(*this); } std::vector<Node*> getOutNodes() const { return ptr_outNodes; } std::vector<Node*> getInNodes() const { return ptr_inNodes; } }; int Node::nextId = 0; int main() { Node n1; Node n2; n1.addOutNode(n2); std::cout << n2.getInNodes().size(); // 此时输出1,符合预期 return 0; }
注意:当前实现存储的是裸指针,需要保证所有Node对象的生命周期长于存储它指针的向量,避免出现悬垂指针。如果需要更安全的内存管理,可以考虑使用
std::shared_ptr<Node>代替裸指针。
内容的提问来源于stack exchange,提问作者rafiki
相关产品推荐
相关产品推荐

