Verschiedene Klassen als Argument?
-
Hallo,
ich habe hier zwei ziemlich identische Funktionen, es sind nur andere Klassen. Ich weiß nicht, wie ich damit umgehen muss?
void scaleToConsole( const Console& console, const Draw& drawing, int& x, int& y ) { double scale_x = console.getColumns() / static_cast<double> ( drawing.getCoordWidth() ); //jeweils ganz andere Werte x = toInt( scale_x * x ); double scale_y = console.getRows() / static_cast<double> ( drawing.getCoordHeight() ); y = toInt ( scale_y * y ); } void scalePToConsole( const Console& console, const Paint& painting, int& x, int& y ) { double scale_x = console.getColumns() / static_cast<double> ( painting.getCoordWidth() ); //jeweils ganz andere Werte x = toInt( scale_x * x ); double scale_y = console.getRows() / static_cast<double> ( painting.getCoordHeight() ); y = toInt ( scale_y * y ); }
Jetzt könnte ich das Paint-Zeug in Draw integrieren,
void scaleToConsole( const Console& console, const Draw& drawing, int& x, int& y, std::string how_to_scale ) { if ( how_to_scale == "draw") { double scale_x = console.getColumns() / static_cast<double> ( drawing.getDrawCoordWidth() ); x = toInt( scale_x * x ); double scale_y = console.getRows() / static_cast<double> ( drawing.getDrawCoordHeight() ); y = toInt ( scale_y * y ); } else if ( how_to_scale == "paint" ) { double scale_x = console.getColumns() / static_cast<double> ( drawing.getPaintCoordWidth() ); x = toInt( scale_x * x ); double scale_y = console.getRows() / static_cast<double> ( drawing.getPaintCoordHeight() ); y = toInt ( scale_y * y ); } }
dann würde es so weitergehen
/*weitere Funktionen müssen wie im ersten Fall nicht dupliziert werden dafür aber überall ein weiteres Argument*/ void bufferDot( Console& console, const Draw& drawing, int x, int y, std::size_t ch_idx, bool show, std::string how_to_scale ) { scaleToConsole( console, drawing, x, y, how_to_scale ); if ( how_to_scale == "draw" ) { if ( x >= 0 && x < console.getColumns() && y >= 0 && y < console.getRows() ) { std::size_t out_idx = static_cast<std::size_t> ( console.getColumns() * y + x ); console.outbuffer.at( out_idx ) = drawing.chars.at( default_draw ).at( ch_idx ); if ( show ) console.writeBuffer(); //lässt den Weg der Dots folgen } } else if ( how_to_scale == "paint" ) { std::size_t out_idx = 0; if ( x >= 0 && x < console.getColumns() && y >= 0 && y < console.getRows() ) { out_idx = static_cast<std::size_t> ( console.getColumns() * y + x ); console.outbuffer.at( out_idx ) = drawing.chars.at( default_paint ).at( ch_idx ); if ( show ) console.writeBuffer(); } x ++; if ( x >= 0 && x < console.getColumns() && y >= 0 && y < console.getRows() ) { out_idx = static_cast<std::size_t> ( console.getColumns() * y + x ); console.outbuffer.at( out_idx ) = drawing.chars.at( default_paint ).at( ch_idx ); if ( show ) console.writeBuffer(); } } }
Ich bin damit nicht ganz zufrieden, vorziehen würde ich die erste Lösung, wenn es da was gibt.
-
Zwei Ideen:
1. Draw und Paint eine gemeinsame Basisklasse geben.
2. Eine Template-Funktion verwenden:
template <typename T> void scaleToConsole( const Console& console, const T& drawing, int& x, int& y ) { double scale_x = console.getColumns() / static_cast<double> ( drawing.getCoordWidth() ); //jeweils ganz andere Werte x = toInt( scale_x * x ); double scale_y = console.getRows() / static_cast<double> ( drawing.getCoordHeight() ); y = toInt ( scale_y * y ); }
Mit der gegebenen Information ist es schwierug zu sagen welche Version sinnvoller ist. Ich wuerde wahrscheinlich Version 2 verwenden.
-
2 würde ich auf die Schnelle auch sofort vorziehen, nur muss ich natürlich erst die Umsetzung versuchen.
Bei 1 müsste ich mich erst einlesen.
(soory für die edtits, es sind nur Umformulierungen)
-
Vielleicht sollte ich doch erklären, wie der weitere Code wäre. Eigentlich sind es nur zwei Grundfunktionen, die noch kommen.
void drawDot( Console& console, const Draw& drawing, int dotX1, int dotY1, std::size_t ch_idx, bool show ) { bufferDot( console, drawing, dotX1, dotY1, ch_idx, show ); } void drawLine( Console& console, const Draw& drawing, int dotX1, int dotY1, int dotX2, int dotY2, std::size_t ch_idx, bool show ) { bufferLine( console, drawing, dotX1, dotY1, dotX2, dotY2, ch_idx, show ); }
void paintDot( Console& console, const Paint& painting, int dotX1, int dotY1, std::size_t ch_idx, bool show ) { bufferPDot( console, painting, dotX1, dotY1, ch_idx, show ); } void paintLine( Console& console, const Paint& painting, int dotX1, int dotY1, int dotX2, int dotY2, std::size_t ch_idx, bool show ) { bufferPLine( console, painting, dotX1, dotY1, dotX2, dotY2, ch_idx, show ); }
-
Wenn ich mir jetzt die beiden obigen anschaue, werde ich wohl die template-Lösung nehmen. Muss ich aber erstmal umsetzen. Danke schön.
-
Erklaer doch mal was die Klassen Draw und Paint machen (und was die Unterschiede sind). Vielleicht kann dir dann jemand ein besseres Design vorschlagen.
-
Das würde ich gerne vermeiden. Ich arbeite (als Quartalsprogrammierer) lange genug an dem Zeug. Ist für mich schon ein großer Fortschritt, das ich Kassen eingeführt habe. Läuft ziemlich besser so.
Will das Ding ( rotierende Vectorobjekte vor einem Plasma mit Char-Sroller in der Konsole ) endlich fertigstellen. Ich weiß, wie das geht, aber ständig resigne ich um.
Deshalb würde ich doch gerne einer meiner Klassen vorstellen wollen. Nur heute nicht mehr. Schonmal danke
-
Tschuldigung, wenn ich jetzt ein YouTube-Link zeige, aber nach meinen großspurigen Worten wollte ich zeigen, das ich nicht... naja
Dies hatte ich vor längerer Zeit gemacht, die Technik ist noch rudimentär.
https://www.youtube.com/watch?v=1X0m-sGXEB4
first look at my first little graphx-demo in windows-console
-
Sorry, war gestern etwas angetrunken. Wenn ich wieder auf dem Dampfer bin, melde ich mich wieder.
Ich glaube nämlich, auch eine Basisklasse ist keine schlechte Idee.