2012-01-26 9 views
0

テキストファイルから読み込むコードがいくつかあり、ファイルの一部がgzipされています。私は、basic_istreamsを生成する関数を持つことでストリームのユーザーがデータをどのように処理しているかを知らない、または気にしなくても、賢いことができると思いました。Boost filtering_streamクリーンアップ

basic_istream<char>* openFile(const string& filename); 

を...と解析クラスは、関数を呼び出し、カバーの下に何が起こっているのかを知りません。だから私は書いています。問題はクリーンアップにあります。私が実際にやっていることはちょうどfstreamを開いているとき、私はストリームを削除することができ、私はすべて設定されています。しかし、filtering_streamではより複雑になります。ここでは、サンプルコードgzip圧縮されたファイルを読むためにfiltering_streamを作成するには、次のようになります。

std::ifstream file (filename, std::ios_base::in | std::ios_base::binary); 
boost::iostreams::filtering_istream in; 
in.push (boost::iostreams::gzip_decompressor()); 
in.push (file); 

...しかし、私は関数呼び出しよりも長生きするためにそれらを必要とするので、明らかに私の場合、私は、スタック上のこれらのオブジェクトを作成することはできませんし、彼らコピーコンストラクタブルではありません。だから私は新しいifstreamと新しいfiltering_istreamを割り当てる必要があり、呼び出し側はfiltering_istreamしか見ることができず、ifstreamを削除する方法もありません(filtering_istreamはあなたのために削除しません)。

これを扱う?私は多くの不器用な解決策を考えることができます - basic_istream*と復活させるためのbasic_istream*のリストの両方を返してください。基本的にcleanup()クロージャのように動作するオブジェクトを返します。私は本当に満足しているとは思えません。あなたが提供できるガイダンスについて事前に感謝します。

答えて

2

生ポインタの代わりにshared_ptr(stdまたはboost)を返すのはどうですか?次に、それぞれのコンポーネントをすべて削除する方法を知っている関数オブジェクトにdeleterを設定できます。例えば

basic_istream<char>* openFile(const string& filename) 
{ 
    if(normal_file) 
    { 
     return boost::shared_ptr<basic_istream<char> >(however_you_create_stream); 
    } 
    else 
    { 
     // GZIPed file. 
     return boost::shared_ptr<basic_istream<char> >(filtering_stream, CleanupStreams(filtering_stream_ptr, raw_stream_ptr)); 
    } 
} 
1

たぶん、あなたはboost::iostreams::filtering_istreamをサブクラス化し、istreamへのポインタを取ることを覚えているし、破壊にそれを削除しますpush_cleanupメンバ関数、のような(と基底クラスのコースの呼び出しpush()の)気にいらを追加することができます。次に、boost::iostreams::filtering_istreamではなく、このサブクラスのインスタンスを使用して返します。