首页 > 解决方案 > 如何控制共享 ptr 引用计数?

问题描述

我正在为我的游戏引擎创建一个资源管理器。基本上,它有一个 unordered_map,将资源的路径作为键存储,作为值存储加载的资源。

这是负责加载资产的代码。

std::shared_ptr<T> LoadAsset(const String& _path)
{
    if (auto asset = m_assets.find(_path); asset != m_assets.end()) {
        return std::static_pointer_cast<T>(asset->second);
    }

    auto asset = std::move(LoadAssetInternal(_path));
    if (!asset) {
        return nullptr;
    }

    m_assets[_path] = std::move(asset);

    return std::static_pointer_cast<T>(m_assets[_path]);
}

问题是当我调用 LoadAsset 方法时,当我删除持有资源的变量时,返回的 shared_ptr 变量总是有 2 个强引用,引用计数变为 1,并且在程序结束时资源永远不会被释放。

示例:

auto tex = LoadAsset<Texture>("Data/Textures/Foo.tga"); // Strong refs = 2
tex = nullptr; // Strong refs = 1 and the loaded Foo.tga is never freed.

标签: c++stdshared-ptr

解决方案


只需创建一个在游戏主循环结束时运行的函数。像这样的东西

void PurgeAssets() {
    for (auto i = m_assets.begin(); i != m_assets.end();) {
        if (i->second.unique()) {
            i = m_assets.erase(i);
        }
        else {
            ++i;
        }
    }
}

推荐阅读