Hallo Stefan,
0) Deine Klasse sollte nicht public von stream und buffer erben. Da
das Verhalten von streams in der Regel über ihre buffer implementiert
werden, würde ich einen buffer implementieren und dann für convenience
einen stream, der einen buffer enthält und diesen als c'tor argument an
den stream weiter reicht.
für 1-3) müsstest Du dann erkennen, ob der stream buffer eines streams
deinem buffer typen entspricht. Hier würde ich dynamic_cast verwenden
(wenn bei Dir verfügbar) (ansonsten wären xalloc()/iword und static_cast
Dein Freund).
1) Manipulatoren, die keine zusätzlichen Argumente nehmen (z.B. endl)
sind Funktionen, die einen ostream als argument nehmen und einen ostream
zurück geben:
1 | std::ostream& clr( std::ostream& out ) {
|
2 | lcd_buffer* const buf = dynamic_cast< lcd_buffer* >( out.rdbuf() );
|
3 |
|
4 | if ( buf )
|
5 | buf->Clear();
|
6 |
|
7 | return out;
|
8 | }
|
2) Manipulatoren, die Argumente nehmen lassen sich gut als Typen mit
Konstruktoren implementieren:
1 | struct goto
|
2 | {
|
3 | goto( int ax, int ay )
|
4 | : x( ax )
|
5 | , y( ay )
|
6 | {}
|
7 |
|
8 | int x, y;
|
9 | };
|
10 |
|
11 | std::ostream& operator<<( std::ostream& out, const goto& target )
|
12 | {
|
13 | lcd_buffer* const buf = dynamic_cast< lcd_buffer* >( out.rdbuf() );
|
14 |
|
15 | if ( buf )
|
16 | buf->goto_xy( target.x, target.y );
|
17 |
|
18 | return out;
|
19 | }
|
3) Da müsstest Du dir merken, dass die nächste Zeile zentriert werden
soll (siehe 1) und dann jedes Zeichen, dass im stream buffer vorbei
kommt zwischen speichern und darauf untersuchen, ob es ein Zeilenumbruch
ist. Das kann man aber auch optimieren, wenn man eine ganze Kette an
Zeichen bekommt, kann man natürlich diese komplett untersuchen.
HTH
Torsten