为什么 std::istream 不承担其 Streambuf 的所有权?

发布于 2024-08-18 21:56:36 字数 1391 浏览 9 评论 0原文

我正在为视频游戏编写某种虚拟文件系统库,例如 CRI Middleware 的 ROFS(请参阅 维基百科)。我使用该库的目的是提供访问我开发的游戏资源的自然方式,这些资源存储一些嵌入在可执行文件中的数据,一些存储在媒体上,一些存储在本地用户的硬盘驱动器上(首选项、保存游戏文件等) 。

访问此类资源应该像进行调用一样简单。

std::auto_ptr<std::istream> defaultConfigIStream(
    fslib.inputStream("self://defaultConfig.ini"));
std::auto_ptr<std::ostream> defaultConfigOStream(
    fslib.outputStream("localappdata://config.ini"));

// Copies default configuration to local user's appdata folder
defaultConfigIStream >> defaultConfigOStream;

实际的操作方式实际上是不同的,有另一个抽象层用于后台加载,但这在这里并不重要。

我想知道的是,考虑到 std::streambuf如何返回 auto_ptr<> (或 unique_ptr<>,您选择)。与 std::[i/o]stream<> 关联的 > 在销毁时不会被删除。

我正在考虑 std::[i/o]stream<> 不会假定在构造时传递给它的 Streambuf 的所有权,因为构造函数不提供所有权语义转移和 Apache 的 STDCXX 参考没有提到所有权的转让(我在互联网上找到的任何 stdlib 参考资料也没有提到)。

我还有哪些选择?我不妨返回一个共享指针并继续监视它,直到 FSlib 管理器保留共享指针的唯一副本,在这种情况下,它将破坏其唯一副本以及 Streambuf。考虑到图书馆的组织模型,这是实用的,但就此事而言,这不是很优雅也没有效率。

我尝试查看 Boost.Iostreams,但对我来说事情似乎更糟,因为流本身的设备类型强烈附加到它们的类型(流的设备必须在其模板参数中定义) )。这个问题似乎使得 Boost.Iostreams 对于我的库来说不可行,因为它需要抽象出流的具体“源/接收器”实现,以便可以无缝地使用流来打开位于可执行文件本身内部的文件,例如,在系统文件系统的文件内或存档类型文件内。

我可以编写一个处理这些问题的容器类,但我宁愿做得更干净(即已经返回流;这就是它所需要的!;)。

建议?

I am writing some sort of virtual file system library for video-games in the likes of CRI Middleware's ROFS (see Wikipedia). My intention with the library is to provide natural means of accessing the resources of the games I develop, which store some data embedded in the executable, some on the media and some on the local user's hard drive (preferences, save game files, etc).

Access to such resources should be as simple as making a call like

std::auto_ptr<std::istream> defaultConfigIStream(
    fslib.inputStream("self://defaultConfig.ini"));
std::auto_ptr<std::ostream> defaultConfigOStream(
    fslib.outputStream("localappdata://config.ini"));

// Copies default configuration to local user's appdata folder
defaultConfigIStream >> defaultConfigOStream;

The actual way of doing things is actually different, with another abstraction layer used for background loading, but that's not important here.

What I want to know is how can I return that auto_ptr<> (or unique_ptr<>, you choose) considering that the std::streambuf<> associated with the std::[i/o]stream<> is not deleted by it when it's destroyed.

I am considering std::[i/o]stream<> doesn't assume ownership over the streambuf passed to it upon construction as the constructor doesn't present transfer of ownership semantics and Apache's STDCXX reference doesn't mention transer of ownership (nor do any of the stdlib references I've found on the internet).

What alternatives do I have? I might as well return a shared pointer and keep watching it until the FSlib manager keep a unique copy of the shared pointer, in which case it would destroy its unique copy as well as the streambuf. That's practical, considering the library's organizational model, but this isn't very elegant nor efficient for that matter.

I've tried taking a look at Boost.Iostreams, but it seems things are even worse with it for me, as streams themselves have their Device types strongly attached to their type (the Device for a stream has to be defined in its template parameter). This problem seems to make the use of Boost.Iostreams unfeasible for my library, as it needs to abstract away the concrete "source/sink" implementation of the streams so that streams can be used seamlessly to open a file located inside the executable itself, inside a file from the system's file system or inside an archive-type file, for example.

I could write a container class that handles these issues, but I'd rather do it more cleanly (i.e. just return the stream already; that's all it should need! ;).

Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你怎么敢 2024-08-25 21:56:36

您可以从 istream 派生自己的流类。 ostream,设置缓冲区
在构造函数中并在析构函数中销毁它。

类似于:

class config_istream : public std::istream {
public:
    config_istream(std::string name) : 
      std::istream(fslib.InputStream(name.c_str())) 
    {
    }

    ~config_istream() { delete rdbuf(); }
};

看看fstream类是如何实现的,它们处理类似的问题(filebuf必须与fstream一起删除)

You could just derive your own stream classes from istreamresp. ostream, set the buffer
in the constructor and destroy it in the destructor.

Something like:

class config_istream : public std::istream {
public:
    config_istream(std::string name) : 
      std::istream(fslib.InputStream(name.c_str())) 
    {
    }

    ~config_istream() { delete rdbuf(); }
};

Have a look on how the fstream classes are implemented, they deal with a similar problem (filebuf has to be deleted together with fstream)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文