以下の注記行に未処理の例外読み取り位置0x00000008(NULL値の読み取り)があります。エラーに至るまでの関連メソッドが含まれています(以下の例に続く):
イベントメソッド:
Event::Event(Event::EVENTTYPE type) : eventType(type) { }
KeyEventメソッド:
class KeyboardKeyEvent : public Event {
public:
//...
int GetKey() const;
protected:
//...
};
int KeyboardKeyEvent::GetKey() const {
return this->_scancode; //Errors out here. "this" returns 0x000000
}
KeyboardKeyEvent::KeyboardKeyEvent(int key, Event::EVENTTYPE type) : Event(type), _scancode(key) { }
KeyDownEventメソッド:
KeyboardKeyDownEvent::KeyboardKeyDownEvent(int scancode) : KeyboardKeyEvent(scancode, Event::KEYBOARD_KEYDOWN) { }
イベントハンドラメソッド:
bool EventHandler::EnqueueEvent(Event* event) {
if(event == NULL) return false;
try {
this->_eventQueue.push(event);
} catch (...) {
return false;
}
return true;
}
Event* EventHandler::DequeueEvent() {
if(this->_eventQueue.empty() == false) {
Event* result = new Event(*this->_eventQueue.front());
delete this->_eventQueue.front();
this->_eventQueue.pop();
return result;
}
return NULL;
}
メインループシーケンス:
if(_eh->HasEvents()) {
Event* nxtEvent = _eh->DequeueEvent();
switch(nxtEvent->GetType()) {
case Event::KEYBOARD_KEYDOWN:
allegro_message("You pressed the %d key!", dynamic_cast<KeyboardKeyDownEvent*>(nxtEvent)->GetKey());
break;
default:
/* DO NOTHING */;
}
delete nxtEvent;
nxtEvent = NULL;
}
これがスライスの問題であることはわかっていますが、なぜ発生しているのか、どのように修正すればよいのかわかりません(実際、考えてみると、おそらく「要求されたタイプに変換できません」エラーです)。プログラムをステップスルーするときは_scancode
常に適切な値ですが、2番目の行dynamic_cast<KeyboardKeyDownEvent*>(nxtEvent)->GetKey()
が実行されるとエラーがスローされます。ダブルキャストもdynamic_cast<KeyboardKeyDownEvent*>(dynamic_cast<KeyboardKeyEvent*>(nxtEvent))->GetKey()
同じエラーで失敗します。
編集:
いくつかの調整の後、このバリアントは完全に機能します。
if(_eh->HasEvents()) {
switch(_eh->PeekEvent()->GetType()) {
case Event::KEYBOARD_KEYDOWN:
allegro_message("You pressed the %s key!", scancode_to_name(dynamic_cast<KeyboardKeyDownEvent*>(_eh->PeekEvent())->GetKey()));
break;
case Event::MOUSE_BUTTONDOWN:{
Mouse::BUTTONS btn = dynamic_cast<MouseButtonDownEvent*>(_eh->PeekEvent())->GetButton();
if(btn == Mouse::BUTTON2) {
allegro_message("You pressed the %d button!", dynamic_cast<MouseButtonDownEvent*>(_eh->PeekEvent())->GetButton());
}
}
break;
default:
/* DO NOTHING */;
}
}