问题
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?
回答1:
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.)
回答2:
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;
}
来源:https://stackoverflow.com/questions/4354659/having-a-streams-streambuf-persist-beyond-streams-destruction