开发者

Having a stream's streambuf persist beyond stream's destruction?

Is it possible to have a stream's streambuf persist after the destruction of its originating stream's destruction?

streambuf* f() {
    ifstream my_开发者_高级运维stream;
    // ...
    return my_stream.rdbuf();
}

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

I.e., I want the pointer to the streambuf object returned by f() to remain valid even after my_stream goes out of scope. At some later time, I want to set some other stream's streambuf to the saved streambuf.

Is this possible? If so, how?


It's not possible. std::ifstream constructs, owns and destroys its buffer. The only reason it's "exported" through rdbuf is to allow redirection of std::cin etc. In the GNU implementation, the buffer is a simple member (not a pointer).

std::ifstream does not export the rdbuf() member with an argument. One of its parent classes does, but this should be shadowed by the redefinition of rdbuf in std::basic_ifstream with signature

std::filebuf *rdbuf() const;

std::filebuf is also non-copyable.

(The rdbuf(std::streambuf *) member can be retrieved by casting to std::ios. Using this will cause the familiar nasal demons.)


To get what you want, create and manage the filebuf/streambuf for yourself. You can create istreams or ostreams on the streambuf as you need them.

Like the following:

#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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜