我想将当前对象的指针传递给新创建的相同类型的对象。 我试着这样,但不知何故,新对象prev字段指向自己。我正在使用Microsoft Visual C ++编译器。
Class A{
A *prev;
A(A* a)
{
prev = a;
}
vector<A> addToVector()
{
vector<A> res;
res.push_back(A(this));
return res;
}
};
现在,当我从向量中获取结果并将其添加到队列时,指针指向自身而不是其前任。出了什么问题?
---编辑
这里是代码片段,我将新状态添加到矢量并返回它们
const int dim = 3;
int goal[] = {1,2,3,4,5,6,7,8,0};
class State{
public:
vector<int> board;
const State *prev;
int g;
int h() const{
int res = 0;
for(int i=0; i<dim*dim; i++){
if(goal[i] != board[i]) res++;
}
return res;
}
inline bool operator==(const State &other) const{
bool eq = true;
for(int i=0; eq && i<dim*dim; i++){
eq = board[i] == other.board[i];
}
return eq;
}
inline bool operator<(const State& other) const{
return g + h() > other.g + other.h();
}
inline State& operator=(const State& other){
this->board = other.board;
this->g = other.g;
this->prev = other.prev;
assert(this != prev);
return *this;
}
State(int a[], int b, const State *p){
board.assign(a, a+dim*dim);
g = b;
prev = p;
assert(prev != this);
}
bool isSolution(){
bool isSol = true;
for(int i=0; i<dim*dim && isSol; i++){
isSol = board[i] == goal[i];
}
return isSol;
}
vector<State> getSuccessors(){
vector<State> successors;
// find zero
bool found = false;
int z_pos;
for(int i=0; i<dim*dim && !found; i++){
found = board[i] == 0;
if(found) z_pos = i;
}
switch(z_pos){
case 0:
{
// 1st row left
int n1[] = {board[1], 0, board[2], board[3],board[4],board[5],board[6],board[7],board[8]};
// 1st columnn up
int n2[] = {board[3], board[1], board[2], 0,board[4],board[5],board[6],board[7],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
} break;
case 1:
{
// 1st row left
int n1[] = {board[0], board[2], 0, board[3],board[4],board[5],board[6],board[7],board[8]};
// 1st row right
int n2[] = {0, board[0], board[2], board[3],board[4],board[5],board[6],board[7],board[8]};
// 2nd column up
int n3[] = {board[0], board[4], board[2], board[3],0,board[5],board[6],board[7],board[8]};
State s1 (n1, g+1, this);
State s2 (n2, g+1, this);
State s3 (n3, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
successors.push_back(s3);
} break;
case 2:
{
// 1st row right
int n1[] = {board[0], 0, board[1], board[3],board[4],board[5],board[6],board[7],board[8]};
// 3rd column up
int n2[] = {board[0], board[1], board[5], board[3],board[4],0,board[6],board[7],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
} break;
case 3:
{
// 1st column up
int n1[] = {board[0], board[1], board[2], board[6],board[4],board[5],0,board[7],board[8]};
// 1st column down
int n2[] = {0, board[1], board[2], board[0],board[4],board[5],board[6],board[7],board[8]};
// row 2 left
int n3[] = {board[0], board[1], board[2], board[4],0,board[5],board[6],board[7],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
State s3(n3, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
successors.push_back(s3);
} break;
case 4:
{
// row 2 right
int n1[] = {board[0], board[1], board[2], 0,board[3],board[5],board[6],board[7],board[8]};
// row 2 left
int n2[] = {board[0], board[1], board[2], board[3],board[5],0,board[6],board[7],board[8]};
// column 2 up
int n3[] = {board[0], board[1], board[2], board[3],board[7],board[5],board[6],0,board[8]};
// column 2 down
int n4[] = {board[0], 0, board[2], board[3],board[1],board[5],board[6],board[7],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
State s3(n3, g+1, this);
State s4(n4, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
successors.push_back(s3);
successors.push_back(s4);
} break;
case 5:
{
// row 2 right
int n1[] = {board[0], board[1], board[2], board[3],0,board[4],board[6],board[7],board[8]};
// column 3 up
int n2[] = {board[0], board[1], board[2], board[3],board[4],board[8],board[6],board[7],0};
// column 3 down
int n3[] = {board[0], board[1], 0, board[3],board[4],board[2],board[6],board[7],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
State s3(n3, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
successors.push_back(s3);
} break;
case 6:
{
// row 3 left
int n1[] = {board[0], board[1], board[2], board[3],board[4],board[5],board[7],0,board[8]};
// column 1 down
int n2[] = {board[0], board[1], board[2], 0,board[4],board[5],board[3],board[7],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
} break;
case 7:
{
// row 3 right
int n1[] = {board[0], board[1], board[2], board[3],board[4],board[5],0,board[6],board[8]};
// row 3 left
int n2[] = {board[0], board[1], board[2], board[3],board[4],board[5],board[6],board[8],0};
// column 2 down
int n3[] = {board[0], board[1], board[2], board[3],0,board[5],board[6],board[4],board[8]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
State s3(n3, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
successors.push_back(s3);
} break;
case 8:
{
// row 3 right
int n1[] = {board[0], board[1], board[2], board[3],board[4],board[5],board[6],0,board[7]};
// column 3 down
int n2[] = {board[0], board[1], board[2], board[3],board[4],0,board[6],board[7],board[5]};
State s1(n1, g+1, this);
State s2(n2, g+1, this);
successors.push_back(s1);
successors.push_back(s2);
} break;
}
return successors;
}
void getPath(){
assert(prev == this);
cin.get();
}
};
void solve(){
priority_queue<State> openSet;
set< vector<int> > closedSet;
int init[] = {1,0,3,4,2,6,7,5,8};
State initial(init,0,NULL);
openSet.push(initial);
while(!openSet.empty()){
State n = openSet.top();
assert(&n != n.prev); //FAILS
openSet.pop();
if(n.isSolution()){
cout << "openSet size: " << openSet.size() << endl;
cout << "closedSet size: " << closedSet.size() << endl;
n.getPath();
break;
}
else if(closedSet.find(n.board) != closedSet.end()){
; // skip
}
else{
closedSet.insert(n.board);
vector<State> successors = n.getSuccessors();
for(int i=0; i<successors.size(); i++){
if(closedSet.find(successors[i].board) == closedSet.end()) openSet.push(successors[i]);
}
}
}
}
int main(){
//freopen("packrec.in", "r", stdin);
//freopen("packrec.out", "w", stdout);
//int t; cin >> t; while(t--)
solve();
return 0;
}
答案 0 :(得分:0)
随着你的建设,似乎无法获得this == this->prev
。但是,这只能保持对象保持足够长的时间。我怀疑他们没有。证明这一点的最简单方法是断言prev
:
A::A(A* p): prev(p) { assert(this != this->prev); }
A::A(A const& a): prev(a.prev) { assert(this != this->prev); }
A& A::operator= (A const& a) {
this->prev = a.prev;
assert(this != this->prev);
}
我怀疑被引用的原始对象在某个时刻消失了,并且该位置被一个不幸地引用自身的对象重用。你快乐地传递对象并保持指向这些对象的指针使它成为一个可能的候选者。如果您的代码不完整(且大多数不相关),则无法再现该问题,因此我无法确认这是否确实存在问题。
答案 1 :(得分:0)
如果不读取(长)上下文代码,则需要注意不要在超出范围的对象上调用addToVector
。因为直接创建类型为A
的本地对象一定是非法的(因为向量可以比它长),所有构造函数A::A
都应该是私有的(复制构造函数除外,vector
必须访问)和对象应该从工厂函数返回,其中addToVector
是一个。
通过定义局部变量来编写一个循环,您打算创建一系列链接对象很容易,但因为在循环的每次迭代中局部地址都相同,所以所有对象看起来都是相同的。这很容易引起自我链接。
啊,我在上下文代码中搜索了addToVector
,它根本就没用过。通用建议就是这样。顺便提一下,这是在你编辑扩展代码之后。