所以我有一些代码可以从文本文件中读取,有些文件是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()闭包的对象;等等 - 但我想不出任何我真正满意的事情。提前感谢您提供的任何指导。
答案 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
。