【问题标题】:Global Access to a Singleton's Data全局访问单例数据
【发布时间】:2016-03-01 13:24:18
【问题描述】:

所以我正在制作一个我想使用资产管理器的图形应用程序(游戏)。对于这门课,我决定使用单例设计。所以在我的 main.cpp 中,我会加载类似...

ASSET_MANAGER.LoadImage("res/graphics/background.png", "background");

这是上面一行中使用的宏/方法的含义。这是一种代码混搭,我必须让事情变得更简单,而不是在这里粘贴几百行代码。

资产管理器.h

#define ASSET_MANAGER AssetManager::GetAssetManager()
#define DEBUG

class AssetManager {
public:
static AssetManager &GetAssetManager();

//-----------------------------------------------------------------------------
// Purpose: Load a new image for the game to use. This function will store an
//          instance of the asset in memory (in a hash map corresponding with
//          the data type provided.
//
// param file: The location on disk of the asset
// param key: The string you use to receive this asset (defaults to the path str)
//-----------------------------------------------------------------------------
bool LoadImage(const char *file, const char *key = "");

//-----------------------------------------------------------------------------
// Purpose: Returns the image
//
// param key: The string used to store the asset in memory
//-----------------------------------------------------------------------------
ALLEGRO_BITMAP *GetImage(const char *key);

//-----------------------------------------------------------------------------
// Purpose: Destroys an asset that is presumably no longer needed by the game.
//          This function is good for performance so that you don't use more
//          RAM than you need to.
//
// param key: The string you use to receive this asset (defaults to the path str)
//-----------------------------------------------------------------------------
void DiscardImage(const char *key);
private:
    AssetManager();

    ~AssetManager();

    std::map<const char *, std::shared_ptr<ALLEGRO_BITMAP>> _ImageMap;
}

资产管理器.cpp

AssetManager &AssetManager::GetAssetManager() {
    static AssetManager instance;
    return instance;
}

bool AssetManager::LoadImage(const char *file, const char *key) {
    key = key == "" ? file : key;
    std::shared_ptr<ALLEGRO_BITMAP> x(al_load_bitmap(file), al_destroy_bitmap);
    if (!x) {
        fprintf(stderr, "Failed to load %s\n", file);
        return false;
    }
#ifdef DEBUG
    printf("DEBUG: Loaded %s\n", key); //debug
#endif // DEBUG
    _ImageMap.insert(std::pair<const char *, std::shared_ptr<ALLEGRO_BITMAP>>(key, x));
    return true;
}

ALLEGRO_BITMAP *AssetManager::GetImage(const char *key) {
    return _ImageMap.find(key) != _ImageMap.end() ? _ImageMap.at(key).get() : nullptr;
}

void AssetManager::DiscardImage(const char *key) {
    _ImageMap.erase(key);
#ifdef DEBUG
    printf("DEBUG: Discarded %s\n", key); //debug
#endif // DEBUG
}

这个类只能在我初始化资产管理器的类中工作,而我希望它可以在我称为 ASSET_MANAGER 的任何地方工作。它编译得很好,只有当我尝试在不同的类中使用管理器并将其传递给 allegro 函数时它才会崩溃,因为它返回的是 null 而不是正确的 allegro 数据类型。我对此有什么不明白的地方?

【问题讨论】:

  • 也许你可以解释它在其他地方不起作用的方式?它不编译吗?它会崩溃吗?它只加载小猫吗?
  • 附带说明,除非您专门使用字符串文字并小心谨慎,否则 const char* 作为映射键几乎没有用,因为您映射的是指针,而不是字符串。首选std::string
  • +molbdnilo 它编译得很好,但是在没有定义 ASSET_MANAGER 的类中,它没有获取数据。 GetImage() 函数只返回 null 而不是我加载的数据。这会导致 allegro 崩溃应用程序,因为它无法呈现 null。
  • 这几乎可以肯定是因为您正在映射指针。
  • 问题是您使用字符串的位置作为键而不是其内容。例如,如果你 LoadImage("foo"...)char[] foo = "foo"; ... GetImage(foo, ...) 将失败。

标签: c++ singleton assets allegro5


【解决方案1】:

地图中的 Char* 存储位置,而不是使程序认为它为空的数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-27
    • 2019-07-18
    • 1970-01-01
    • 2021-07-04
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多