为什么我的类变量会在方法之间更改其值?

时间:2018-12-01 23:49:12

标签: c++ animation

我正在尝试将位图动画加载到屏幕上。我有一个浮点变量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中的值。

这是我的动画头文件的外观:

#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 Cpp文件:

 #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 :(得分:1)

您的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(该名称的下一个最接近的“匹配”),因此它仅保留其原始的未指定值(实际上,读取未初始化的变量会导致您的程序具有未定义的行为)。

因此,您看到,您的成员变量根本不会“更改”,您永远不会正确设置它。您已经知道是否在该构造函数中放入了一些诊断输出来检查该值,并查看它是否是您认为的正确值。其余代码均不相关或不必要。

配置正确的编译器should have warned you about this