-2

現在のオブジェクトのポインターを、同じ型の新しく作成されたオブジェクトに渡したいです。このように試してみましたが、どういうわけか新しいオブジェクトの 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;
}
4

2 に答える 2

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); 
}

参照されていた元のオブジェクトがある時点でなくなり、不運にも自分自身を参照しているオブジェクトによってその場所が再利用されたのではないかと思います。これらのオブジェクトへのポインターを保持することと組み合わせて、オブジェクトを自由に渡すことができれば、候補になる可能性があります。不完全な(そしてほとんど無関係な)コードでは問題を再現できないため、これが実際に問題であるかどうかを確認できませんでした。

于 2012-05-13T02:04:03.103 に答える
0

addToVector(長い) コンテキスト コードを読み取らずに、スコープ外になるオブジェクトを呼び出さないように注意する必要があります。タイプのローカルオブジェクトを直接作成することは違法であるに違いないためA(ベクターがそれよりも長く存続する可能性があるため)、すべてのコンストラクターA::Aはプライベートである必要があり(アクセスする必要があるコピーコンストラクターを除くvector)、オブジェクトは代わりにファクトリ関数から返される必要があります。addToVector1であります。

ローカル変数を定義して一連のリンクされたオブジェクトを作成するループを作成するのは簡単ですが、ループの各反復でローカルのアドレスが同じであるため、すべてのオブジェクトが同一に見えます。これにより、簡単にセルフリンクが発生する可能性があります。

ああ、コンテキスト コードで検索しaddToVectorましたが、まったく使用されていません。したがって、一般的なアドバイスは有効です。ちなみに、これはコードを拡張するための編集後です。

于 2012-05-13T12:59:19.633 に答える