我试图创建一个包含指针向量的节点类。这是我的代码:
node.h:
#ifndef NODE_H
#define NODE_H
class node
{
public:
vector<node*> next;
void add_arc(node & a)
string some_string;
#endif
node.cpp:
void node::add_arc(node & a)
{
node *b = &a;
next.push_back(b); //only copyies nodes
}
main.cpp中:
int main()
{
vector<node> nodes;
node a;
node b;
node c;
a.somestring = "a";
b.somestring = "b";
c.somestring = "c";
a.add_arc(b); //a should point to b
a.add_arc(c); //a should point to c
nodes.push_back(a);
nodes.push_back(b);
nodes.push_back(c);
cout << nodes[0].next.size() << endl; // prints "2", works fine
cout << nodes[0].next[0]->some_string << endl; //empty
}
我认为这就像重载push_back一样简单:
void push_back(vertex * pointer)
{
next.push_back(pointer);
}
但我认为我真的需要一个复制构造函数或其他方法才能使其工作。我如何为指针向量做这个?
编辑:我想我没有解释清楚。看看这个问题的答案: Segmentation fault when accessing a pointer's member function in a vector 制作&#39; a&#39;引用对我不起作用
答案 0 :(得分:1)
您的代码按预期生成正确的输出(请参阅online demo):
2
b
然而,这个结果与运气有某种关系,因为在你的代码片段中:
nodes
向量中的节点是原始对象的副本,包括其所有指针然而,在更复杂的代码中,您很快会以悬空指针结束。 想象一下:
next
指针无效。 main
调用的函数中。在这种情况下,只要从此函数返回,所有本地节点都将被销毁,并且向量的节点将指向不再存在的对象。 UB保证! 您的设计无法识别节点都属于同一图表。
快速而肮脏的出路:始终从免费商店创建节点,并将其存储在vector<node*>
中。
vector<node*> nodes;
node *a = new node("a"); // Imagine a node constructor
node *b = new node("b");
a->add_arc(b); //change signature, to accept a pointer
nodes.push_back(a);
nodes.push_back(b);
有一个更好的方法:进一步改进以前的方法,但使用shared_ptr<node*>
来确保不再引用的节点(既不是节点向量,也不是由弧线)自动销毁。
还有一种更好的方法:将节点封装在表示图形的类中。在这种情况下,您可以考虑使用vector<nodes>
并使用向量中目标节点的索引替换next
中的指针。没有指针,但完美的图形副本将更容易。没有更多的内存管理麻烦。
class node // just to give the general idea
{
public:
vector<int> next; // not usable without the graph
void add_arc(int a)
string id;
};
class graph {
vector<node> nodes;
public:
void add_node (node a);
void add_arc (string from, string to);
node& operator[] (size_t i);
...
};