我有一个正在为硕士论文开发的项目。在这个项目中,我有一个名为 node 的父类和其他一些子类,例如 AND 类。我还有一个名为 graph 的类,其中的节点使用std :: map存储。我得出的结论是,我不需要使用 std :: map 。使用 std :: vector ,我可以更快地访问图内的节点。
AND类具有两个向量:一个向量用于其输入,另一个向量用于其输出。我有两种方法可以将节点的指针添加到这两个向量之一。
当我在图类中从map更改为vector时,AND节点内的某些指针丢失了其值。
我对指针做了一些研究,在我看来我没有做错任何事情。我在这里迷路了。
class node{
protected:
unsigned int id;
public:
virtual void pushOutput(node* param){}
virtual void pushInput(node* param,bool param_polarity){}
}
class AND : public node{
vector <node*> inputs;
vector <node*> outputs;
public:
void pushOutput(node* param) override;
void pushInput(node* param,bool param_polarity) override;
}
void AND::pushOutput(node* param){
this->outputs.push_back(param);
}
//AND::pushInput is omitted, but it is pretty similar to AND::pushOutput except with a bunch of ifs.
class graph {
protected:
// map<unsigned int,AND> all_ANDS;
vector<AND> all_ANDS;
public:
AND* pushAnd(unsigned int index,AND AND_obj);
AND* findAnd(unsigned int);
}
AND* graph::pushAnd(unsigned int index, AND AND_obj){
// std::pair<std::map<unsigned int,AND>::iterator,bool> ret;
// ret=this->all_ANDS.insert(pair<unsigned int,AND>(index,AND_obj));
all_ANDS.push_back(AND_obj);
return &all_ANDS.back();
}
AND* graph::findAnd(unsigned int param){
// return &this->all_ANDS.find(param)->second;
return &all_ANDS[param];
}
请注意,注释行是代码正常工作的版本。
使用读取文件的方法(省略了一些内容):
bool polar;
AND* AND_ptr;
unsigned int rhs0;
for(int l=0;l<A;l++)
{
and_index++;
AND AND_obj(and_index*2);
AND_ptr=this->pushAnd(and_index*2,AND_obj);
//reading info from file here and putting on rhs0 and polar.
AND_ptr->pushInput(findAnd(rhs0),polar);
findAnd(rhs0)->pushOutput(findAnd(and_index*2));
findAny(rhs0)->printNode();
}
如果我使用方法 graph :: findAnd()获取节点地址以将其推入另一个节点的向量内: inputs 或 outputs >保存在这些向量上的地址指向一些垃圾,但只有经过一段时间后,它才首先指向正确的位置,如 AND :: printNode()所示。
换句话说,graph :: findAnd()返回一个无效的指针,尽管在std :: map版本中它仍然可以正常工作。
我很确定我的问题是由于对指针的某些知识不足。虽然当我检查类似Vector of object pointers returns odd values这样的其他类似问题时,我的代码对我来说似乎还可以。
答案 0 :(得分:1)
您必须考虑迭代器无效。从std::vector::push_back
的{{3}}开始:
如果新的size()大于Capacity(),则所有迭代器和 引用(包括过去的迭代器)无效。 否则,只有过去的迭代器才无效。
此处的“引用”在广义上使用,即指向元素的指针也无效。原因是std::vector
保证将其数据保存在连续的内存块中,因此,当您推送新元素时,先前的元素可能必须四处移动。
我了解您的代码太少,无法提供更多建议。只需注意,添加新元素时std::list
不会使迭代器无效(std::map
也是一样)。但是,这样做的代价通常是不值得支付的(没有std::list
的数据本地性才是杀手))。另一方面,如果容器的全部目的是在不使引用无效的情况下启用引用元素,则这可能是一个有效的选择。
答案 1 :(得分:-1)
不要保留指向<ng-template *ngFor="let symptomtype of symptomtypes; let index=index;">
<h2> {{symptomtype.Description}}</h2>
<li *ngFor="let symptom of symptoms | filterSymptom: index + 1]">
<p"> {{symptom.Description}}</p>
</li>
</ng-template>
中存储的对象的指针。 vector
结构将其所有成员保留在连续的内存块中,因此,当向量变大时,可能需要分配新的块,从而使指向vector
中对象的所有指针无效。
我也强烈建议不要使用vector
的原始指针。这是一种不好的做法,这使得管理对象的生存期非常困难,这在这里确实出错了。
例如,您可以对对象使用vector
个中的vector
个。然后,您可以将其他std::shared_ptr
存储到其他集合中的那些对象。