我有一个类,用于将图像文件加载到位图并保持对这些位图的引用。我希望稍后在关闭应用程序之前解除这些资源的释放。
所以我的班级(是一个单身人士)设计如下:
class ImageManager
{
public:
static ImageManager &getInstance();
ImageManager(ImageManager const&) = delete;
void operator=(ImageManager const&) = delete;
void loagImage(char *location);
~ImageManager();
private:
ImageManager();
ALLEGRO_BITMAP *image = nullptr;
}
真正的构造函数中没有什么。只需加载与处理位图相关的附加组件。没有创建原始指针。
loadImage()
实现如下:
void ImageManager::loadImage(char *location)
{
if(!location)
{
throw std::invalid_argument("Location cannot be null.");
}
image = al_load_bitmap(location);
}
析构函数定义为
ImageManager::~ImageManager()
{
if(image)
{
al_destroy_bitmap(image); // Here I get the access violation exception.
}
}
这个类在main.cpp
中的使用方式如下:
int main(int argc, char *args[])
{
ImageManager &imgManager = ImageManager::getInstance();
imgManager.loadImage("valid/location");
return 0;
}
如果我在加载位图的相同函数中调用al_destroy_bitmap()
,则没有错误。它只发生在我尝试在析构函数中调用它时。
我在使用VS17的Windows 10上。我在同一个主题上看到了很多问题,但我无法使用那里的答案找出错误。如果您需要,我还会链接到两个allegro方法:
编辑:
我的getInstance()
方法是:
ImageManager &ImageManager::getInstance()
{
static ImageManager instance;
return instance;
}
编辑2:
确切的错误是0xC0000005: Access violation reading location 0xDDDDDDF1.
Allegro 5不像单身人士这样的全局游戏。
要记住的事情:
1)在调用al_init
之前发生全局对象或静态初始化的全局调用。这意味着在其构造函数内调用allegro函数将失败。
2)全球静力学主力和主力。这意味着他们的析构函数将在allegro通常关闭后运行。 al_install_system挂钩atexit关闭它的库,除非你明确告诉它不要。这意味着如果你很幸运的话,对像al_destroy_bitmap
这样的快板功能的调用会失败并且会发生段错误。
在调用al_uninstall_system之前,在atexit和main退出之前或之前,你必须明确地“关闭”你的ImageManager实例。
将instance
更改为指针,让getInstance
创建一个实例,并在destroyInstance
之前添加显式return 0
调用来删除实例,因为在退出main之后你不再拥有一个不受你控制的破坏/释放序列。