Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Przekazywanie własnego obiektu do funkcji jako std::ostream

Ostatnio zmodyfikowano 2015-08-04 16:28
Autor Wiadomość
DejaVu
Temat założony przez niniejszego użytkownika
[C++] Przekazywanie własnego obiektu do funkcji jako std::ostream
» 2015-08-04 10:54:38
Przykład:
C/C++
#include <streambuf>
#include <vector>

class Bufor
    : public std::basic_streambuf < char, std::char_traits < char > >
{
public:
    Bufor( cmn::FileBinary & _file )
        : m_file( _file )
    {
        m_buffer.reserve( 1024 );
    }
private:
    typedef typename std::basic_streambuf < char, std::char_traits < char > >::int_type int_type;
    typedef std::char_traits < char > traits;
    cmn::FileBinary & m_file;
    std::vector < char > m_buffer;
   
    virtual int_type overflow( int_type c ) {
        if( !traits::eq_int_type( c, traits::eof() ) ) {
            m_buffer.push_back( c );
            if( m_buffer.size() >= m_buffer.capacity() )
                 sync();
           
        }
        return traits::not_eof( c );
    }
   
    // This function is called when stream is flushed,
    // for example when std::endl is put to stream.
    inline virtual int sync( void )
    {
        m_file.write( & m_buffer[ 0 ], m_buffer.size() );
        m_buffer.clear();
        return 0;
    }
};

class Strumien
    : public cmn::FileBinary
     , public std::basic_ostream < char, std::char_traits < char > >
{
   
public:
   
    Strumien()
        : std::basic_ostream < char, std::char_traits < char > >( & buf )
         , buf( * this )
    {
    }
   
private:
    Bufor buf;
};

void funkcja( std::ostream & _stream )
{
    _stream << ":)";
}

int main()
{
    Strumien strumien;
    funkcja( strumien );
}
P-135672
Elaine
» 2015-08-04 16:28:12
Zachowanie tego kodu jest niezdefiniowane z powodu kolejności tworzenia obiektów, w dodatku jest niepotrzebnie skompilkowany i wolny. std::streambuf samo potrafi buforować, po co robić to w overflow, skoro w ten sposób potrzebne jest wywołanie funkcji wirtualnej co każdy znak?

Lepszy przykład:
C/C++
#include <streambuf>
#include <ostream>
#include <array>

template < typename Char, typename Traits = std::char_traits < Char >>
class basic_example
    : public std::basic_streambuf < Char, Traits >
{
public:
    basic_example() {
        reset_buffer();
    }
private:
    using int_type = typename Traits::int_type;
   
    void reset_buffer() {
        this->setp( & buffer[ 0 ], & buffer[ buffer.size() - 1 ] );
    }
   
    bool flush_buffer() {
        // actual write goes here
        // data to flush: range from this->pbase() to this->pptr()
        // if(failed) { return false; }
        reset_buffer();
        return true;
    }
   
    virtual int_type overflow( int_type c ) override {
        if( !Traits::eq_int_type( c, Traits::eof() ) ) {
            * this->pptr() = Traits::to_char_type( c );
            this->pbump( 1 );
        }
        return flush_buffer() ? Traits::not_eof( c )
            : Traits::eof();
    }
   
    virtual int sync() override {
        return flush_buffer() ? 0
            : - 1;
    }
   
    std::array < Char, 1024 / sizeof( Char ) > buffer;
};

using example = basic_example < char >;

template < typename Char, typename Traits = std::char_traits < Char >>
class basic_example_stream
    : private basic_example < Char, Traits >
     , public std::basic_ostream < Char, Traits >
{
public:
    basic_example_stream()
        : std::basic_ostream < Char, Traits >( static_cast < basic_example < Char, Traits >*>( this ) )
    {
    }
};

using example_stream = basic_example_stream < char >;
P-135691
« 1 »
  Strona 1 z 1