流的streambuf持续超越流的破坏?

时间:2010-12-04 17:01:22

标签: c++ iostream

在销毁其原始流的销毁之后,是否有可能让流streambuf持续存在?

streambuf* f() {
    ifstream my_stream;
    // ...
    return my_stream.rdbuf();
}

void g() {
    streambuf *s = f();
    // ...
    ifstream my_new_stream;
    my_new_stream.rdbuf( s );
}

即,即使在streambuf超出范围之后,我希望f()返回的my_stream对象的指针仍然有效。稍后,我想将其他流streambuf设置为已保存的streambuf

这可能吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:2)

这是不可能的。 std::ifstream构造,拥有并销毁其缓冲区。它通过rdbuf“导出”的唯一原因是允许重定向std::cin等。在GNU实现中,缓冲区是一个简单的成员(不是指针)。

std::ifstream不会使用参数导出rdbuf()成员。它的一个父类确实如此,但这应该被rdbuf中带有签名的std::basic_ifstream的重新定义所掩盖

std::filebuf *rdbuf() const;

std::filebuf也是不可复制的。

(可以通过强制转换为rdbuf(std::streambuf *)来检索std::ios成员。使用此会导致熟悉的鼻腔恶魔。)

答案 1 :(得分:1)

要获得您想要的,请自行创建和管理filebuf / streambuf。您可以根据需要在streambuf上创建istreams或ostreams。

如下所示:

#include <iostream>
#include <fstream>
#include <memory>
#include <string>

using namespace std;

shared_ptr<streambuf> f()
{
    auto ret = make_shared<filebuf>();
    if( !ret->open("filebuf-test.cpp", ios::in) )
        exit(1);
    return ret;
}

void g(streambuf *sb)
{
    istream is(sb);

    string line;

    while(getline(is, line)) {
        cout << line << '\n';
    }
}

int main()
{
    auto p = f();
    g(p.get());
    return 0;
}