how do I override a std::filebuf?

会有一股神秘感。 提交于 2019-12-09 23:08:00

问题


I have a Visual Studio 2008 C++ 03 application using STLPort 5.2.1 where I would like to use a custom std::filebuf implementation. For example:

class MyFileBuf : public std::filebuf
{
protected:
    virtual int_type sync()
    {
        // breakpoint here never fires
        return std::filebuf::sync();
    };

    virtual std::streamsize xsputn( const char_type* p, std::streamsize n )
    {
        // breakpoint here never fires
        return std::filebuf::xsputn( p, n );
    };

    virtual int_type overflow( int_type c = traits_type::eof() )
    {
        // breakpoint here never fires
        return std::filebuf::overflow( c );
    };
};

class MyFileStream : public std::ofstream
{
public:
    MyFileStream() : std::ofstream( new MyFileBuf() ) { clear(); };
    ~MyFileStream() { delete rdbuf(); };
};

int main()
{
    MyFileStream fs;
    fs.open( "test.txt" );
    fs << "this is a test" << std::endl;
    return 0;
}

Unfortunately, none of the members of MyFileBuf are ever called. If I step through the code, I see that the << operator goes to

stlpd_std::basic_streambuf<char,stlpd_std::char_traits<char> >::xsputn(const char* __s, long int __n)
stlpd_std::basic_streambuf<char,stlpd_std::char_traits<char> >::sputn(const char* __s, long int __n)
stlpd_std::basic_ostream<char,stlpd_std::char_traits<char> >::_M_put_nowiden(const char* __s)
stlpd_std::operator<<<stlpd_std::char_traits<char> >(stlpd_std::basic_ostream<char,stlpd_std::char_traits<char> >& , const char* __s )
main()

where I would expect the top of the callstack to be:

MyFileBuf::xsputn(const char* p, long int n)

The files are, however, written correctly. Can anybody help me understand where I am going wrong?


回答1:


Thanks @jahhaj and @DanielKO for your help.

The solution appears to be something like this:

#include <iostream>
#include <fstream>
using namespace std;

class MyFileBuf : public std::filebuf
{
protected:
    virtual int_type sync()
    {
        return std::filebuf::sync();
    };

    virtual std::streamsize xsputn( const char_type* p, std::streamsize n )
    {
        return std::filebuf::xsputn( p, n );
    };

    virtual int_type overflow( int_type c = traits_type::eof() )
    {
        return std::filebuf::overflow( c );
    };
};

class MyFileStream : public std::ostream
{
public:
    MyFileStream() : std::ostream( 0 ) { init( &buf_ ); };
    MyFileStream( const char* filename, std::ios_base::openmode mode = std::ios_base::out )
        : std::ostream( 0 )
    {
        init( &buf_ );
        this->open( filename, mode );
    }

    bool is_open() const { return buf_.is_open(); };

    void close() { buf_.close(); };

    void open( const char* filename, std::ios_base::openmode mode = std::ios_base::out )
    {
        buf_.open( filename, mode );
    };

    std::filebuf* rdbuf() { return &buf_; };

private:
    MyFileBuf buf_;
};

int main()
{
    MyFileStream fs( "test.txt" );
    fs << "this is a test" << std::endl;
    return 0;
}

Example



来源:https://stackoverflow.com/questions/11836485/how-do-i-override-a-stdfilebuf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!