F
direktor schrieb:
Der Anwendungszweck ist vergleichbar mit einem Computerspiel, wo manche Einheiten eine (absolute) Position haben und andere zusätzlich zur Position noch eine Ausrichtung (also wo die Einheit ist und wohin sie schaut). Dann gibt es Hilfsfunktionen, die manchmal nur mit Koordinaten arbeiten und manchmal mit Koordinaten und einer Ausrichtung.
Anstatt da immer zwei Parameter zu übergeben, dachte ich mir, es sei am besten, daraus eine neue Klasse zu basteln und den Einheiten eine DirectedPosition (so heisst die Klasse aktuell) zu geben. Diese DirectedPosition habe ich von Position geerbt um schnell von DirectedPosition in Position konvertieren zu können und damit ich .x statt .pos.x schreiben kann. Wartungsprobleme sehe ich dabei nicht, denn DirectedPosition wird das einzige Kind bleiben und daran etwas zu ändern habe ich auch nicht vor. Es ist halt schön, DirectedPosition by Reference zu übergeben und in einer anderen Funktion was daran ändern zu können, obwohl sie eigentlich nur eine Position entgegen nimmt. Es ist ja nicht so, dass ich eine Riesenhierarchie auf Position aufbaue.
Kann man sicher so machen, obwohl ich persönlich bei solchen Hilfsfunktionen die Variante mit den zwei Argumenten bevorzuge. Meiner Erfahrung nach kommt es öfter mal vor, dass man eine solche Funktion irgendwann z.B. mit einem Winkel aufrufen möchte, der nicht in einem Position/Winkel-Paar gespeichert ist - vielleicht weil man diesen gerade in einer lokalen Variable ausgerechnet hat. Dann musst du dir erst eine DirectedPosition zusammenbauen um die Funktion aufrufen zu können - das fände ich umständlich und vielleicht auch nicht elegant, wenn das Paar konzeptionell z.B. keine wirkliche "Position mit Richtung" ist, sondern etwas anderes, das du mit der Hilfsunktion ausrechnen willst.
direktor schrieb:
Den Winkel hatte ich auch vor, implizit überall in Bogenmass zu speichern.
Ist das so eine gute Idee?
Ja, warum nicht. Die trigonometrischen Funktionen wie sin() , cos() , etc. erwarten ohnehin Bogenmaß. Es sollte allerdings aus den Kommentaren/der Dokumentation hervorgehen, welche Einheit hier verwendet wird.
Man kann es auch etwas umständlicher entwerfen, wenn man vermeiden will, dass es zu Missverständnissen kommt, und wie erwähnt die Einheit zu einem Teil des Typen machen, der dann implizite Konvertierung unterstützt. z.B:
Degrees angle1 = 90.0_deg;
Radians angle2 = (0.5 * PI)_rad;
cout << angle1 + angle2 << endl;
180.0 degrees
(Auf genaue Implementierung gehe ich jetzt nicht ein)
... oder über Template-Parameter wie es z.B. in std::chrono gemacht wird um die verschiedenen Zeiteinheiten abzubilden.
Für ein einfaches Spiel ist das aber sicher übertrieben - wenn du allerdings ein Navigationssystem für eine 500-Millionen-Euro-Rakete schreibst, ist es sicher nicht verkehrt, jegliche Missverständnisse von vornherein auszuschließen
Finnegan