Почему мой измененный 2D-вектор сбрасывает мои данные - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь сохранить объект в двухмерном векторе. Вектор должен быть измерен во время выполнения. Поэтому я использую функцию изменения размера, как упоминалось во многих других вопросах.

Это пример кода моей проблемы. Так что код может не иметь смысла, но я получаю ту же ошибку.

animation.h

class myPoint{
public:
    int x, y;
    myPoint(){}
    myPoint(int x, int y) : x(x), y(y) {}
};

class AnimationFrame {
private:
    std::vector<std::vector<myPoint>> sprites; //the important part
public:
    void addSpritePoint(myPoint gridPos, myPoint tilePos);
    ...
};

class Animation {
private:
    std::vector<AnimationFrame*> animationFrames;
public:
    ...
};

Animation.cpp

Animation::Animation() {}

int Animation::addAnimationFrame() {
    AnimationFrame *newAnimationFrame = new AnimationFrame();
    this->animationFrames.emplace_back(newAnimationFrame);
}

//AnimationFrame class

AnimationFrame::AnimationFrame(){
    int w = 3; //just for the test
    int h = 3;
    this->sprites.resize(w, std::vector<myPoint>(h, myPoint(0,0)));
}

void AnimationFrame::addSpritePoint(myPoint gridPos, myPoint tilePos) {
    this->sprites[gridPos.x][gridPos.y] = tilePos;
    //printf(""); //breakpoint here
}

main.cpp

int main() {

    Animation *a = new Animation();
    a->addAnimationFrame();

    a->getAnimationFrame(0).addSpritePoint(myPoint(0,0), myPoint(1,1));
    a->getAnimationFrame(0).addSpritePoint(myPoint(0,1), myPoint(2,2));
    a->getAnimationFrame(0).addSpritePoint(myPoint(0,2), myPoint(3,3));
}

Я ожидаю, что 2D-вектор спрайтов из моего класса AnimationFrame содержит значения. Когда первая точка останова в точке (1,1) находится в спрайтах (0,0), но когда я теперь перехожу к следующей точке останова, значения в спрайтах (0,0) снова равны (0,0). Таким образом, это сбрасывает значение. И я понятия не имею, почему.

1 Ответ

0 голосов
/ 26 января 2019

Проблема связана с тем, что Animation::getAnimationFrame() возвращает копию своих внутренних данных:

AnimationFrame Animation::getAnimationFrame(int frame) const;

Таким образом, это изменяет временный объект и не имеет никакого эффекта после вычисления полного выражения:

a->getAnimationFrame(0).addSpritePoint(myPoint(0,0), myPoint(1,1));

Исправление простое: возврат по ссылке:

const AnimationFrame& Animation::getAnimationFrame(int frame) const
{
    return *animationFrames[frame];
}

AnimationFrame& Animation::getAnimationFrame(int frame)
{
    return *animationFrames[frame];
}

(да, вам нужна постоянная и неконстантная версия)

...