首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将std::流对象从一个管理器传递到另一个管理器

将std::流对象从一个管理器传递到另一个管理器
EN

Stack Overflow用户
提问于 2014-01-06 16:06:01
回答 3查看 216关注 0票数 2

我正在为我的游戏实现一个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的包装器?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-06 16:22:18

考虑实现一个流缓冲器 (可以作为参数传递)。当需要缓冲区上的I/O时,在缓冲区上创建一个std::istream或std::ostream。

这种方法将允许您使用std::[i/o]stream访问正确格式化的I/O,而无需付出任何努力(也就是说,您只需定义从流中添加或获取字节意味着什么,而不是格式化。

代码应该如下所示:

代码语言:javascript
复制
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操作符:

你需要写的是:

代码语言:javascript
复制
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将如下所示:

代码语言:javascript
复制
// 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 exception
票数 1
EN

Stack Overflow用户

发布于 2014-01-06 16:20:59

通常的解决方案是通过引用传递,但是根据您的描述,流将在一个单独的函数中创建并返回,并且应该存在于创建函数的生存期之后。传统上,您会返回一个指向动态分配的流的指针,被调用者必须删除该流。(这就是std::auto_ptr设计的目的。)在C++11中,这个解决方案仍然有效(但您可能希望使用std::unique_ptr )。或者,您可以为返回使用移动语义,尽管它们不尊重多态类型。换句话说:如果locateFile创建了一个std::ifstream,那么您用它的返回值初始化的局部变量必须是一个std::ifstream,而不仅仅是一个std::istream。这可能暴露了太多的locateFile内部,并使std::auto_ptr/std::unique_ptr解决方案更可取。

票数 1
EN

Stack Overflow用户

发布于 2014-01-06 16:22:26

有三种通过溪流的方法(我认为):

  • 作为参数(对函数的非const引用)
  • 作为封装在智能指针中的返回值(std/boost::shared_ptr或unique_ptr)
  • 移动语义(编译器可能不支持)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20954061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档