std::streambuf überladen ...
-
Also, hab für einen User von einem anderen Forum mal einer Problematik versucht zu lösen. Das Problem ist, dass er er in einen Stream was reinschreiben will, und das dann in 2 Streams (file & cout z.B.) ausgegeben werden soll.
Dafür eignet es sich ja am besten, direkt auf Buffer ebene zu arbeiten:
#include <streambuf> template<typename _elem, typename _traits = std::char_traits<_elem> > class basic_dualstreambuf : public std::basic_streambuf<_elem, _traits > { std::basic_streambuf<_elem, _traits>* m_first; std::basic_streambuf<_elem, _traits>* m_second; protected: typedef typename _traits traits_t; typedef typename traits_t::int_type int_t; virtual int_t overflow(int_t c = traits_t::eof()) { if (traits_t::eq_int_type(c, traits_t::eof()) == true) return traits_t::not_eof(c); c = m_first->sputc(c); return (traits_t::eq_int_type(c, traits_t::eof()) == false ? m_second->overflow() : c); } virtual int sync() { return (m_first->sync() != -1 ? m_second->sync() : -1); } public: explicit two_streambuf (std::basic_streambuf<_elem, _traits>* ptr_first, std::basic_streambuf<_elem, _traits>* ptr_second) : m_first(ptr_first), m_second(ptr_second) {} }; typedef basic_dualstreambuf<char> dualstreambuf; typedef basic_dualstreambuf<wchar_t> wdualstreambuf;. Da meckert der VC++ 2005 aber:
_console_test_project.h(187) : error C2248: 'std::basic_streambuf<_Elem,_Traits>::overflow' : cannot access protected member declared in class 'std::basic_streambuf<_Elem,_Traits>' with [ _Elem=char, _Traits=std::char_traits<char> ] c:\programme\microsoft visual studio 8\vc\include\streambuf(297) : see declaration of 'std::basic_streambuf<_Elem,_Traits>::overflow' with [ _Elem=char, _Traits=std::char_traits<char> ] _console_test_project.h(184) : while compiling class template member function 'int basic_dualstreambuf<_elem>::overflow(int)' with [ _elem=char ] _console_test_project.h(203) : see reference to class template instantiation 'basic_dualstreambuf<_elem>' being compiled with [ _elem=char ]wenn ich es bsw. mal so teste:
#include <fstream> #include <iostream> int main() { std::ofstream file_stream("test.txt"); dualstreambuf buffer(std::cout.rdbuf(), file_stream.rdbuf()); std::clog.rdbuf(&buffer); std::cout << "Test 001" << std::endl; }. Jemand eine Idee wie ich das umgehen kann?
Hab mich nach meinem ersten Versuch (s. oben) mal schlau gemacht aber auch nur gefunden, dass overflow überladen werden muss ... und das hab ich ja nunmal versucht

Vlg Deviloper
-
Ja - der Compiler hat recht. Du darfst nicht die protected Methode eines anderen Objekts aufrufen und geanu das tust Du hier. Benutze doch genauso das sputc wie bei m_first auch. Außerdem ist die Abfrage aud EOF doppelt vorhanden.
Für sync gilt das gleiche.Das ganze könnte etwa so laufen:
virtual int_t overflow( int_t c = traits_t::eof() ) { if (traits_t::eq_int_type(c, traits_t::eof())) return traits_t::not_eof(c); const char cc = traits_t::to_char_type( c ); return (traits_t::eq_int_type( m_first->sputc(cc), traits_t::eof() ) || traits_t::eq_int_type( m_second->sputc(cc), traits_t::eof() ))? traits_t::eof(): traits_t::not_eof(c); } virtual int sync() { return (m_first->pubsync() == 0 && m_second->pubsync() == 0? 0: -1); }Im übrigen solltest Du die Buffer immer wieder zurücksetzen - insbesondere den von clog.
Das hatten wir auch schon mal .. hier ist so eine Weiche implementiert. Die Weiche übernimmt auch das Rücksetzen.
Gruß
Werner
-
zugriffsschutz. die elementfunktionen sind protected, damit kann deine klasse sie nicht (über einen zeiger auf basic_streambuf) aufrufen, nur über this->... ist ein zugriff auf geschützte memberfunktionen möglich. das würde bedeuten, du müsstest ableiten.
nur: dann könntest du deinem dualstreambuf nicht zwei streambuffer zuweisen, vor allem könntest du deinem dualstreambuf nicht den streambuf von cout/cin zuweisen.das lässt dir zwei alternativen.
(a) du moppelst doppelt und bufferst die ausgabe deines streambufs nochmal auf den beiden streambufs, die du als zeiger verwendest (damit ist dein streambuf so eine art proxy-stream), du kannst natürlich den internen buffer deiner streambufs auf 0 setzen, dann hast du de facto auch nur mehr einen buffer. //anmerkung: sehe gerade, das Werner Salomon genau so etwas vorschlägt
(b) du schreibst dir eine eigene streamklasse, die zwei streambufs für die ausgabe verwendet.PS namen mit einem unterstrich beginnen zu lassen ist böse!
-
template<typename _elem, typename _traits = std::char_traits<_elem> > class basic_dualstreambuf : public std::basic_streambuf<_elem, _traits > { std::basic_streambuf<_elem, _traits>* m_first; std::basic_streambuf<_elem, _traits>* m_second; protected: virtual int_type overflow(int_type c = traits_type::eof()) { return ((m_first && m_second && !traits_type::eq_int_type(m_first->sputc(c), traits_type::eof()) && !traits_type::eq_int_type(m_second->sputc(c), traits_type::eof())) ? traits_type::not_eof(c) : traits_type::eof()); } public: explicit basic_dualstreambuf (std::basic_streambuf<_elem, _traits>* ptr_first, std::basic_streambuf<_elem, _traits>* ptr_second) : m_first(ptr_first), m_second(ptr_second) {} }; typedef basic_dualstreambuf<char> dualstreambuf; typedef basic_dualstreambuf<wchar_t> wdualstreambuf;... warum wird nur ein verdammtes Zeichen angehangen? Da stimmt doch was nicht

-
hola
vielleicht hilft dir einer der beiden links weiter:
http://spec.winprog.org/streams/
http://www.icce.rug.nl/documents/cplusplus/cplusplus05.htmlMeep Meep