【发布时间】:2019-12-06 13:28:26
【问题描述】:
我正在为我的游戏引擎创建一个资源管理器。基本上它有一个 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.
【问题讨论】:
-
你能发一个minimal reproducible example吗?
-
您想避免只阅读那些您知道有人仍在积极使用它们的资源(否则,您愿意重新加载资源)?然后在缓存中只保留资源的
weak_ptr。 -
共享对象有两个所有者 -
tex和您的缓存表。 -
如果您不希望
m_assets容器保持对象处于活动状态,请在其中存储weak_ptr而不是shared_ptr。否则,您需要从资产缓存中显式删除引用。
标签: c++ std shared-ptr