我剛剛完成了我的OpenGL + GLUT遊戲的基本異常系統的實現。我拋出的退出遊戲的異常處理得很好,還有一些其他斷言異常,但後來我試圖通過刪除圖像文件夾導致圖像加載失敗,並且該特定異常似乎沒有被捕獲。它導致應用程序關閉消息「此應用程序請求運行時以非常規方式終止」。從代碼的特定部分拋出的異常沒有被捕獲
這是try/catch塊來處理所有的異常,它的應用程序類(它是在頭文件,因爲它是一個模板函數)的在線靜態方法:
#pragma once
#include "logging.hpp"
#include "utils.hpp"
#include "throwables.hpp"
#include <cassert>
#include <exception>
namespace core
{
class application
{
public:
static const char * const tag;
template <class T>
static int run(int argc, char *argv[], const int width, const int height,
int x, int y, const char * const title) throw (const std::exception &)
{
int res = 0;
logging * const log = logging::get();
try
{
assert(log != NULL);
log->setverbosity(logging::info);
dbgcode(log->setverbosity(logging::verbose));
T * const g = T::get();
if (!g)
{
log->wtf(tag, "run: g is NULL! are we out of memory?");
throw core::assertexception();
}
T::envinit(argc, argv);
g->initialize(width, height, x, y, title);
g->run();
}
catch(const core::exitexception &e)
{
// hopefully everything is deallocated properly this way
log->i(tag, "run: exit message recieved");
res = 0;
}
catch(const core::assertexception &e)
{
utils::unexpectederror(title);
res = 1;
}
catch(const core::errorexception &e)
{
utils::error(title);
res = 1;
}
log->i(tag, strfmt() << "exiting with code " << res);
return res;
}
};
}
,這是
void sprite::load(const char * const filename) throw (const assertexception &, const errorexception &)
{
if (!filename) // this exception is handled perfectly
{
log->wtf(tag, strfmt() << "load: filename is NULL! what the hell did you pass me?" << img);
throw assertexception();
}
fromtex = false;
// generate and bind a DevIL image
ilGenImages(1, &img);
ilBindImage(img);
// attempt to load the sprite as a DevIL image
if (!ilLoadImage(filename)) // this exception is never caught even if I change this to if(true)
{
log->e(tag, strfmt() << "load: failed to load " << filename << ", image id = " << img);
throw errorexception(); // never caught when thrown
}
...
這裏是我的throwables.hpp/throwables.cpp,我定義所有:拋出,它永遠不會處理的異常(它裏面G-執行>運行,所以它是try塊內)的代碼我的自定義例外:
HPP:
#pragma once
#include <stdexcept>
#include <string>
namespace core
{
class exception : public std::runtime_error
{
public:
exception(const std::string &info);
};
class assertexception : public exception
{
public:
assertexception();
};
class errorexception : public exception
{
public:
errorexception();
};
class exitexception : public exception
{
public:
exitexception();
};
}
CPP:
#include "throwables.hpp"
namespace core
{
exception::exception(const std::string &info)
: std::runtime_error(info)
{}
// assertexception
assertexception::assertexception()
: exception("an assertion has occurred - check the log file")
{}
// errorexception
errorexception::errorexception()
: exception("an error has occurred - check the log file")
{}
// exitexception
exitexception::exitexception()
: exception("exit message recieved")
{}
}
編輯:另外,在這裏是指那些utils的:: *錯誤funcs中我打電話:
void unexpectederror(const wxString &gamename)
{
// TODO: make everything unicode friendly
// TODO: get all strings from xmls for easy localization
wxSafeShowMessage(gamename + wxT(" - Unexpected error"),
wxT("An unexpected error has occurred. Please report this bug")
wxT(" and attach your lastsession.log file"));
}
void error(const wxString &gamename)
{
wxSafeShowMessage(gamename + wxT(" - Error"),
wxT("An error has occurred. Please check your lastsession.log")
wxT(" for more info and check for <error> messages. Please report it if you believe it is a bug"));
}
void error(const wxString &title, const wxString &text)
{
wxSafeShowMessage(title, text);
}
的std ::例外是被抓在主,順便說一句:
#include "dungeoncrawler.hpp"
#include "application.hpp"
using namespace core;
int main(int argc, char *argv[])
{
static const char * const tag = ".main";
static const char * const title = "DungeonCrawler";
try
{
return application::run<dungeoncrawler::game>(argc, argv, 800, 450, -1, -1, title);
}
catch(const std::exception &e)
{
utils::unhandledexception(title, e);
logging::get()->wtf(tag, "unhandled exception, exiting with code 0");
return 0;
}
assert(false); // this code should never be reached
logging::get()->wtf(tag, "what?! this code should be unreachable! exiting with code 0");
utils::error(wxString(title), wxT("Unexpected behaviour occurred. Please report this bug to the developer"));
return 0;
}
可能值得注意的是,在任何時候你都不會捕獲'std :: exception'。雖然它是你所定義的所有優秀和吸引人的東西,但是當你沒有寫*的某些代碼拋出一個異常時,它會全部崩潰。 – 2013-04-21 16:24:25
std ::異常被捕獲主 – 2013-04-21 16:27:39