Search code examples
c++abstract-classderived-classmutation

Change the field of a derived class object but the change was recovered after returning


I override the create function.

void IBlock::create() {
    Cell a;
    a.setCoords(0, 3);
    a.setblank(false);
    Cell b;
    b.setCoords(1, 3);
    b.setblank(false);
    Cell c;
    c.setCoords(2, 3);
    c.setblank(false);
    Cell d;
    d.setCoords(3, 3);
    d.setblank(false);
    vector<Cell> row2;
    row2.push_back(a);
    row2.push_back(b);
    row2.push_back(c);
    row2.push_back(d);
    block.push_back(row2);
}

But when I try to change the coordinates of IBlock using right and setX in cell, and output their coordinates,

void Board::right() {
    bool movable = true;
    if (getCurrent() == nullptr) {
        return;
    }
    for (auto ro : getCurrent()->block) {
        int x = ro.back().getX() + 1;
        int y = ro.back().getY();
        if (x >= col || (board[y][x])) {
            movable = false;
        }
    }
    if (movable) {
        for (auto ro : getCurrent()->block) {
            for (auto co : ro) {
                int x = co.getX();
                int y = co.getY();
                board[y][x] = false;
            }
        }

        for (auto ro : getCurrent()->block) {
            for (auto co : ro) {
                co.setX(co.getX() + 1);
                int x = co.getX();
                int y = co.getY();
                board[y][x] = true;
                cout << x << y << "!";
            }
        }
    }
}
void Cell::setX(int a)
{
    this->x = a;
}

I get the coordinates as 13!23!33!43!. But when I get the coordinates back in main, I get the coordinates as 03!13!23!33! just as the coordinates before the movement?

HOW CAN I MAKE THE CHANGE OF COORDINATES STAY? THANK YOU VERY MUCH!!


Solution

  • for (auto co : ro) makes a copy of each iterated object rendering calls like co.setX() useless. It is like passing parameters by value. If you need your loop (function) to mutate the iterable's elements (arguments), bind them to a reference loop variable (parameter).

    Use for (auto& co : ro), see this answer for more details.

    Same goes for for (auto ro : getCurrent()->block) loops, use const auto& to avoid extra copies.