我正在为我的游戏实现一个ResourceManager,我遇到了一个关于流的小问题。
在“资源管理器”中,有一个Locator对象搜索文件。当定位器找到文件时,它返回一个ResourceStream对象(virtual ResourceStream * FileLocator::locateFile(const String &name);)。然后,Loader对象解析文件并创建一个资源对象(例如virtual Resource * ResourceLoader::parseStream(ResourceStream * stream);)。
问题是,我不知道如何实现ResourceStream,因为我不知道std::streams是如何使用的。作为一种良好的实践,流是如何在对象之间传递的?是通过指针传递还是移动语义,考虑到流将在作用域的末尾被删除?在上面的问题中,我应该如何使溪流移动?我应该让ResourceStream继承自std::fstream并由std::move传递吗?还是应该使用ResourceStream作为std::streambuf的包装器?
发布于 2014-01-06 16:22:18
考虑实现一个流缓冲器 (可以作为参数传递)。当需要缓冲区上的I/O时,在缓冲区上创建一个std::istream或std::ostream。
这种方法将允许您使用std::[i/o]stream访问正确格式化的I/O,而无需付出任何努力(也就是说,您只需定义从流中添加或获取字节意味着什么,而不是格式化。
代码应该如下所示:
class ResourceStream: public std::streambuf {
    ... // you implement this
};
virtual Resource parseStream(std::streambuf * streambuf)
{
    std::istream    in(streambuf);
    Resource        r;
    in >> r; // assumes an std::istream& operator>>(std::istream&in, Resource& r)
             // is defined
    if(in >> r)
        return r;
    else
        throw std::runtime_error{"bad stream for parsing resource"};
}编辑:
再看一看,这似乎是x-y问题。正确的解决方案是为资源类定义i/o操作符:
你需要写的是:
class Resource {
// ...
};
std::istream& operator >> (std::istream& in, Resource& r) {
    return in after reading from it
}
std::ostream& operator << (std::ostream& out, const Resource& r) {
    return in after writing into it
}在您的模型中,ResourceStream对象将是在定位文件上打开的std::ifstream,您的ResourceManager将如下所示:
// boost::path can be replaced by std::string containing the file path
virtual boost::path FileLocator::locateFile(const String &name);
// locate file and get resource:
auto path = locator.locateFile("serializedresource.data");
std::ifstream input(path);
Resource r;
if(input >> r)
    // r was read correctly
else
    // stream does not contain a serialized r / throw an exceptionhttps://stackoverflow.com/questions/20954061
复制相似问题