6

私は、CRIミドルウェアの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;

実際のやり方は実際には異なり、バックグラウンドの読み込みに別の抽象化レイヤーが使用されますが、ここでは重要ではありません。

私が知りたいのは、に関連付けられているが破棄されたときに削除されないことを考慮して、それをどのように返すことができるかauto_ptr<>(またはunique_ptr<>、選択した場合)です。std::streambuf<>std::[i/o]stream<>

std::[i/o]stream<>コンストラクターは所有権の転送セマンティクスを提示せず、ApacheのSTDCXX参照は所有権のトランサーについて言及していないため、構築時に渡されたstreambufに対する所有権を想定しないことを検討しています(私が見つけたstdlib参照もありません)インターネット上で)。

どのような選択肢がありますか?共有ポインターを返し、FSlibマネージャーが共有ポインターの一意のコピーを保持するまでそれを監視し続けることもできます。その場合、その一意のコピーとstreambufが破棄されます。図書館の組織モデルを考えると、これは実用的ですが、これはあまりエレガントでも効率的でもありません。

Boost.Iostreamsを見てみましたが、ストリーム自体のデバイスタイプがそのタイプに強く関連付けられているため、状況はさらに悪化しているようです(ストリームのデバイスはテンプレートパラメーターで定義する必要があります) )。この問題により、Boost.Iostreamsをライブラリで使用できなくなったようです。これは、ストリームをシームレスに使用して実行可能ファイル自体の内部にあるファイルを開くことができるように、ストリームの具体的な「ソース/シンク」実装を抽象化する必要があるためです。たとえば、システムのファイルシステムのファイル内、またはアーカイブタイプのファイル内。

これらの問題を処理するコンテナクラスを作成することもできますが、もっとクリーンに実行したいと思います(つまり、すでにストリームを返すだけです。必要なのはそれだけです!;)。

提案?

4

1 に答える 1

8

istreamrespから独自のストリームクラスを派生させることができます。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

于 2010-01-18T00:13:21.423 に答える