C++ 当我将int数据成员的初始化值更改为除1以外的任何值时,程序崩溃
早些时候,我将一些数据移动到一个单一对象GamePropertiesManager。在这个类中,我定义了一个名为_gameSpeed的变量,在类构造函数中,我使用初始化列表将其默认设置为1 在另一个类中,我有一个更新循环,(在我的控制之外),它将总是尽可能频繁地更新。我打算这样做,并成功地使用了“速度”变量来减慢更新速度。比如说,将其设置为2,游戏只会每隔一次调用onUpdate更新一次。。如果你看看下面PlayState::onUpdate()的内容,我可能会觉得有道理(我在一位评论者的建议下发布了整个cpp): 我的问题是,当我将初始化列表中的_gameSpeed的值更改为(1)之外的任何值时我的程序在运行时崩溃。我发现这一点特别奇怪,因为我之前将_frameCounter与除1以外的硬编码值和设置为除1以外的值的速度变量进行比较,程序运行正常。对这个问题有什么想法吗C++ 当我将int数据成员的初始化值更改为除1以外的任何值时,程序崩溃,c++,design-patterns,initialization,C++,Design Patterns,Initialization,早些时候,我将一些数据移动到一个单一对象GamePropertiesManager。在这个类中,我定义了一个名为_gameSpeed的变量,在类构造函数中,我使用初始化列表将其默认设置为1 在另一个类中,我有一个更新循环,(在我的控制之外),它将总是尽可能频繁地更新。我打算这样做,并成功地使用了“速度”变量来减慢更新速度。比如说,将其设置为2,游戏只会每隔一次调用onUpdate更新一次。。如果你看看下面PlayState::onUpdate()的内容,我可能会觉得有道理(我在一位评论者的建议下
希望我解释得足够好,谢谢你的帮助 原因几乎是肯定的,因为对于除1以外的任何值,在第一次调用
PlayState::onUpdate
时,if
检查将不会运行,很可能会使某些内容未初始化。如果您的进程是多线程的,多个线程将其设置为onUpdate
,然后您需要向GetInstance
添加足够的锁定,以确保两个相互竞争的线程在第一次(并发)调用时不能创建独立实例,更重要的是,让一个线程发布由另一个线程启动的未完全初始化的实例。如果需要帮助,必须显示更多代码。@SamDeHaan好的,谢谢,恐怕我只是把事情弄得更乱了,我想我已经发布了所有相关信息,但在你的建议下,我已经完整地添加了PlayState,希望附加的上下文能有所帮助:)我想知道,在很多时候都是非法的情况下,哪些书籍/网站不断推荐引导
。\u fruitManager.UpdateFruits()
可能会初始化某些内容。如果没有在first onUpdate()中对它的第一次调用,它就会崩溃?@MarkB是的,我不知道为什么这么多书和老师告诉我,可以在成员变量中使用前导下划线。目前,我正在努力保持一致,但我将在我今后从事的所有项目中取消这种方法。@Holly-如果您确认多线程,我将扩展答案。感谢进一步调查后的观察,您是绝对正确的。我的“解决方案”是将_frameCounter=初始化为游戏速度,然后在if条件后增加它,以确保它在第一次调用时始终进入该条件。。也许我应该重新思考我的架构,但这是我的第一个主要项目,我只是想取得进展:p
#include "PlayState.hpp"
#include "PlayerController.hpp"
#include "AIController.hpp"
#include <stdlib.h>
#include <time.h>
//testin
#include <iostream>
/// Implement PlayState
PlayState::PlayState()
{}
PlayState::~PlayState()
{}
bool PlayState::onCreate()
{
_gameProperties = GamePropertiesManager::GetInstance();
_frameCounter = 0;
application.addKeyListener( *this );
_collisionFlag = false;
//snakes created, intialising a pointer to fruit managaer, controller and opposing snake
_player1 = new Snake();
_player2 = new Snake();
_player1->Initialise(&_fruitManager, new PlayerController(_player1), _player2);
_player2->Initialise(&_fruitManager, new AIController(_player2), _player1);
return true;
}
bool PlayState::onDestroy()
{
return true;
}
void PlayState::onEntry()
{
//seed to randomise food positions later
srand ( time(0) );
}
void PlayState::onExit()
{
}
void PlayState::onUpdate()
{
//TODO: rename _snake speed and maybe make it global gamespeed
++_frameCounter; //FrameCounter can be used to slow the snake down
if(_frameCounter >= _gameProperties->GetGameSpeed())
{
//updating
_fruitManager.UpdateFruits();
_player1->Update(&_collisionFlag);
_player2->Update(&_collisionFlag);
if (_collisionFlag)
application.setState("gameover");
_frameCounter = 0;
}
}
void PlayState::onRender( Canvas& c )
{
_player1->Draw(c);
_player2->Draw(c);
_fruitManager.DrawFruits(c);
}
bool PlayState::onKey (const KeyEvent& key)
{
if( key.key_state == KeyEvent::KB_DOWN ){
switch (key.key){
case KeyEvent::KB_ESC_KEY:
application.exit();
break;
case 'p':
application.setState("pause");
break;
}
}
return true;
}
#include "GamePropertiesManager.hpp"
GamePropertiesManager* GamePropertiesManager::_instance = NULL;
GamePropertiesManager* GamePropertiesManager::GetInstance()
{
if (!_instance) //instance not yet created
_instance = new GamePropertiesManager();
return _instance;
}
void GamePropertiesManager::Destroy()
{
delete _instance;
_instance = 0;
}
GamePropertiesManager::GamePropertiesManager() :
_gameMode(PLAYERVSCOM), _player1Name("Player 1"), _player2Name("Player 2"),
_player1Score(0), _player2Score(0), _matchSurvivor("NONE"), _gameSpeed(1)
{
}
unsigned int GamePropertiesManager::GetGameSpeed()
{
return _gameSpeed;
}