移动资源管理器类的语义
Move semantics for a resource manager class
我正在尝试为我的游戏创建一个资源类(它使用SFMLneneneba API)。基本上,我首先加载所需的资源,然后在需要时获取对它们的引用,以避免资源类的繁重构建。
(我将使用sf::Texture类作为示例)
问题出在负载函数上。为了制作sf::Texture,我必须使用默认的构造函数,然后使用它的loadFromFile函数来获得所需的纹理。假设我有一个包含成对文件名和相应资源的映射:
std::map<std::string, sf::Texture> textures;
sf::Texture texture;
texture.loadFromFile(file);
现在,如果我这样做:
textures.emplace(file, texture);
这将使用复制构造函数来制作另一个sf::Texture。所以我想我应该使用std::move,但显然sf::Texture类没有move构造函数,所以这仍然是一个副本。为了解决这个问题,我现在使用一个包含文件名对和对象各自的unique_pointer的映射。所以我做了:
std::unique_ptr<sf::Texture> texture(new sf::Texture);
texture->loadFromFile(file);
textures.emplace(file, std::move(texture));
以下是完整功能的样子:
void ResourceManager::loadTexture(std::string file)
{
std::unique_ptr<sf::Texture> texture(new sf::Texture);
if (!texture->loadFromFile(file))
{
throw std::runtime_error("ResourceManager::load - Failed to load " + file);
}
auto inserted = mtextures.emplace(file, std::move(texture));
assert(inserted.second);
}
不过,我在移动语义方面没有太多经验,也不确定我是否一切都对。基本上,我错过了什么吗?如果这个问题不属于堆栈溢出,我会很乐意将其转移到适当的站点。
您发布的代码看起来是正确的,给出了您尝试做什么的描述。
地图将被指定为资源的所有者。当它被销毁时,资源也将被销毁,除非有人事先检索到资源(例如,通过std::move
)。
我唯一的建议是在创建指针时使用std::make_unique
(为了异常安全,并使代码更惯用)。除了这些小细节,听起来你的想法是对的。
如果您担心不能有效地移动sf::Texture
,那么就不要移动sf::Texture
。直接在地图中构建它们:
void ResourceManager::loadTexture(const std::string& file)
{
assert(mtextures.find(file) == mtextures.end());
auto& t = mtextures[file];
try {
if (!t.loadFromFile(file)) {
throw std::runtime_error("ResourceManager::load - Failed to load " + file);
}
} catch(...) {
mtextures.erase(file);
throw;
}
}
相关文章:
- 如何维护资源管理器项目视图中当前可见的项目列表
- 编译器资源管理器和 GCC 具有不同的输出
- Windows 资源管理器中的图标在使用 resource.rc 时显示 2 个不同的图标
- 编译器资源管理器(godbolt)如何安全地运行代码?
- 从 GUI 文件资源管理器执行程序,并且不生成终端
- Visual Studio 测试资源管理器找不到我的提升测试
- 通过文件资源管理器获取文件夹目录
- Windows 资源管理器打开文件夹还原
- 如何使用C 浏览目录以创建文件资源管理器
- C++ Android 资源管理器从应用内部目录中读取文件
- 停止SetVolumeMountPoint打开文件资源管理器
- 重新启动资源管理器.exe使用 C++
- 资源管理器
- Visual Studio,在(解决方案资源管理器的)某个筛选器内的所有文件中查找/替换文本
- SHOpenFolder并选择资源管理器更换程序的项目
- 如何在 Windows 资源管理器中捕获用户的左键单击?
- 如何将设备隐藏在资源管理器中
- 资源管理器在 TILE 视图模式下不显示 shell 命名空间扩展的项目详细信息
- 模板中的错误可能是错误的设计资源管理器
- 移动资源管理器类的语义