Почему моя переменная класса меняет свое значение между методами? - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь загрузить растровую анимацию на экран.У меня есть переменная с плавающей точкой holdTime, которая указана для хранения значения "holdtime" для анимации.В моем конструкторе я установил переменную holdtime на 0.1f, но когда я пытаюсь получить доступ к методу в классе, использующем переменную holdTime, значение holdTime изменилось на -107374176f.Так что где-то между моим вызовом конструктора и вызовом метода значение изменилось с 0.1f на -107374176f.

Чтобы сделать вещи немного более понятными, позвольте мне показать вам некоторый код:

Вот файл заголовка для класса Game, здесь я вызываю конструктор класса Animationу него есть переменная holdTime.

  #pragma once

#include "Graphics.h"
#include "Surface.h"
#include "Animation.h"
#include "FrameTimer.h"

class Game
{
public:
    Game( class MainWindow& wnd );
    void Go();
private:
    void UpdateModel();

private:
    MainWindow& wnd;
    FrameTimer ft;
    Surface surf = Surface("Test32x48.bmp");
    Animation testAnimation = Animation(0, 0, 32, 48, 4, surf, 0.1f);
};

Вы видите, что у меня есть это testAnimation внизу класса.Последний аргумент в вызове конструктора - это значение, которое должно быть в holdTime.

. Вот так выглядит мой заголовочный файл Animation:

#include "Surface.h"
#include "Graphics.h"
#include <vector>

class Animation {
public:
    Animation(int x, int y, int width, int height, int count, const Surface& sprite, float holdtime, Color chroma = Colors::Magenta);
    void Update(float dt);
private:
    void Advance();
private:
    std::vector<RectI> frames;
    int iCurFrame = 0;
    float holdTime = 0;
    float curFrameTime = 0.0f;
};

А это Animation Cppfile:

 #include "Animation.h"

Animation::Animation(int x, int y, int width, int height, int count,
    const Surface& sprite, float holdtime, Color chroma)
    :
    sprite(sprite),
    holdTime(holdTime),
    chroma(chroma)
{
    for (int i = 0; i < count; i++)
    {
        frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
    }
}

void Animation::Update(float dt)
{
    curFrameTime += dt;
    while(curFrameTime >= holdTime) {
        Advance();
        curFrameTime -= holdTime;
    }
}

void Animation::Advance()
{
    if (++iCurFrame >= frames.size()) {
        iCurFrame = 0;
    }

}

Существует только один метод, использующий holdTime, и это метод Update(float dt).

Если мы вернемся к классу Game и посмотрим на файл Game.cpp:

#include "MainWindow.h"
#include "Game.h"

Game::Game( MainWindow& wnd )
    :
    wnd( wnd ),
    gfx( wnd )
{
}

void Game::Go()
{
    UpdateModel();
}

void Game::UpdateModel()
{
    testAnimation.Update(ft.Mark());
}

В методе Go() мы вызываем метод UpdateModel(), который в свою очередь вызываетметод Update() в классе анимации.Это означает, что первым методом, который будет выполнен в классе Animation после вызова конструктора, является метод update().Когда я отлаживаю программу, я вижу, что значение holdtime изменилось между вызовом конструктора и вызовом метода Update ().Но я не знаю как, так как я не изменяю значение где-то еще.Также кажется, что новое значение holdTime является значением мусора.

В этом вопросе стало много кода, и он выглядит немного неопрятно, и хотя мне не хватает навыков написания хорошего титула, надеюсь, я дал вам несколько понять, в чем заключается моя проблема.Спасибо!

Обновление:

Вот код класса FrameTimer, поскольку значение, возвращаемое одним из его методов, передается в метод Update():

FrameTimer.H:

#pragma once
#include <chrono>

class FrameTimer
{
public:
    FrameTimer();
    float Mark();
private:
    std::chrono::steady_clock::time_point last;
};

FrameTimer.cpp:

#include "FrameTimer.h"

using namespace std::chrono;

FrameTimer::FrameTimer()
{
    last = steady_clock::now();
}

float FrameTimer::Mark()
{
    const auto old = last;
    last = steady_clock::now();
    const duration<float> frameTime = last - old;
    return frameTime.count();
}

Редактировать: main.cpp:

    int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR pArgs,INT )
    {
        MainWindow wnd( hInst,pArgs );      
            Game game( wnd );
            while( wnd.ProcessMessage() )
            {
                game.Go();
            }
    }

Как видите, метод game.Go()первый метод, который вызывается в main.

1 Ответ

0 голосов
/ 02 декабря 2018

Ваш Animation конструктор неисправен:

Animation::Animation(int x, int y, int width, int height, int count,
    const Surface& sprite, float holdtime, Color chroma)
    :
    sprite(sprite),
    holdTime(holdTime),
    chroma(chroma)
{
    for (int i = 0; i < count; i++)
    {
        frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
    }
}

Здесь вы пытаетесь инициализировать элемент holdTime из параметра holdTime.

За исключением того, что нет параметраholdTime.Существует только параметр holdtime.

Следовательно, вместо этого вы фактически инициализируете элемент holdTime от себя (следующее ближайшее «совпадение» для этого имени), поэтому он сохраняет только свое первоначальное, неуказанное значение (и действительно, чтение неинициализированной переменной приводит к тому, что ваша программа имеет неопределенное поведение).

Итак, вы видите, что ваша переменная-член вообще не «изменяется» - вы никогда не установите ее правильно.Вы бы знали, что если бы вы поместили какой-то диагностический вывод в этот конструктор, чтобы проверить значение и посмотреть, действительно ли это то, что, по вашему мнению, должно быть.Ни один из остального кода не был уместен или необходим.

Правильно настроенный компилятор должен был предупредить вас об этом .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...