提升filtering_stream清理

时间:2012-01-26 15:43:50

标签: c++ boost

所以我有一些代码可以从文本文件中读取,有些文件是gzip压缩的。我认为通过生成一个生成basic_istreams的函数并且流的用户不知道或不关心如何处理数据,我可以聪明一点。所以我写道:

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

...解析类调用该函数,并且不知道幕后发生了什么。问题在于清理。当我实际做的只是打开一个fstream时,我可以删除该流并且我已经完成了设置。但是使用filtering_stream会变得更加复杂。以下是创建filtering_stream以读取gzip压缩文件的示例代码:

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 个答案:

答案 0 :(得分:2)

如何返回shared_ptr(std或boost)而不是原始指针。然后,您可以将删除器设置为一个知道如何删除所有相应组件的函数对象。

例如:

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 :(得分:1)

也许你可以继承boost::iostreams::filtering_istream并添加像push_cleanup成员函数这样的东西,它会指向istream,记住它并在销毁时删除它(当然还要调用它)基类的push())。然后只使用并返回此子类的实例而不是boost::iostreams::filtering_istream