[C++] Przekazywanie własnego obiektu do funkcji jako std::ostream
Ostatnio zmodyfikowano 2015-08-04 16:28
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: #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 ); } 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 ); }
|
|
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: #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() { 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 >; |
|
« 1 » |