Manipulatoren für Länge der Ausgabe
-
Hallo,
ich würde gerne Manipulatoren einführen, um komfortabel festlegen zu können, wie ausführlich Objekte benutzerdefinierter Klassen ausgegeben werden sollen. Also wenn ich ein Objekt a der Klasse A habe, möchte ich
cout << short << a;
oder
cout << long << a;
schreiben können.
Kann man das irgendwie realisieren, ohne eine eigene Klasse, die ostream erweitert, definieren zu müssen?
-
Du könntest so nen Manipulator bauen:
class A { private: // ... // friend für Templateklassen/Funktionen allgemein geht nicht, glaub ich }; class manip<typename C> { private: const A& a_; public: A(const A& a) : a_(a) {} const A& getA() const {return A_;} }; template<typename T> ostream& operator<<(ostream& os, const manip<T>& obj) {} // irgendwie spezialisieren ostream& operator<<(ostream& os, const manip<short>& obj) { os << obj.getA().getAttrib(); return os; }
Alles ungetestet. Aber wenn das klappt, ginge dann:
std::cout << manip<short>(a) << manip<long>(a) << '\n';
-
ingobulla schrieb:
Hallo,
ich würde gerne Manipulatoren einführen, um komfortabel festlegen zu können, wie ausführlich Objekte benutzerdefinierter Klassen ausgegeben werden sollen. Also wenn ich ein Objekt a der Klasse A habe, möchte ich
cout << short << a;
oder
cout << long << a;
schreiben können.
Kann man das irgendwie realisieren, ohne eine eigene Klasse, die ostream erweitert, definieren zu müssen?
Ja. Du kannst Dir eigene Manipulatoren schreiben. Dafür musst Du ostream selbst nicht anfassen. Allerdings ist das kein ganz einfaches Thema, insbesonderes, wenn diese Parameter annehmen können sollen. Eine Suchmaschine hilft Dir weiter...
Und hier gibts einen Artikel im Forum dazu.
-
Hallo ingobulla,
so geht das:
#include <iostream> struct Foo // irgendeine Klasse { Foo() : m_1(11), m_2(22), m_3(33) {} friend std::ostream& operator<<( std::ostream& out, const Foo& foo ); private: int m_1, m_2, m_3; // irgendwelche Parameter }; // -- global FOO_LENGTH-Index namespace { const int FOO_LENGTH = std::ios_base::xalloc(); } // -- die Manipulatoren short_foo und long_foo setzen die 'Rucksackinformation' std::ostream& short_foo( std::ostream& out ) { out.iword( FOO_LENGTH ) = 0; return out; } std::ostream& long_foo( std::ostream& out ) { out.iword( FOO_LENGTH ) = 47; return out; } // -- Die Ausgabefunktion liest die 'Rucksackinformation' aus dem ostream std::ostream& operator<<( std::ostream& out, const Foo& foo ) { out << foo.m_1; // die kurze Fassung if( out.iword( FOO_LENGTH ) > 0 ) // Bem.: falls kein Manipulator vorher gerufen wurde, so ist der Wert =0 { out << "; " << foo.m_2 << "; " << foo.m_3; } return out; } int main() { using namespace std; Foo foo; cout << "kurz " << short_foo << foo << endl; cout << "lang " << long_foo << foo << endl; cout << "kurz " << short_foo << foo << endl; return 0; }
Die Ausgabe hier wäre:
kurz 11 lang 11; 22; 33 kurz 11
Gruß
Werner