Fragen zu Void draw



  • Hallo ich stehe auf dem Schlauch, kann mir jemand erklären was dieses Abschnitt für eine Aufgabe hat?



  • @Dafina-97

    void draw() const { gip_draw_rectangle(x1, y1, x2, y2, blue); } //31-33 Prototypen
    void draw_red() const { gip_draw_rectangle(x1, y1, x2, y2, red); }
    bool does_not_collide_with(const MyRectangle &other) const; // wenn die auf einander stoßen dann falsch holt originalen werte aus memory hier geht es darum das die nicht aufeinander treffen sollenn
    //Zeile 33 = stoßen die kasten aneinader? wenn ja dann ist es falsch ansonsten richtig
    MyRectangle operator=(const double d) const //35-38
    {
    MyRectangle result = *this;
    int tempx, tempy = 0; //wird auf null gesetzt
    tempx = ((result.x2 - result.x1) * d) + result.x1; // 40-41 result x1 und y1 werden berechnet und zugewiesen
    tempy = ((result.y2 - result.y1) * d) + result.y1;
    result.x2 = tempx; // werte werden übernommen
    result.y2 = tempy;
    return result;
    }
    };



  • Ich verstehe deine Frage nicht - und noch weniger verstehe ich, warum man einen operator= mit const macht, das ergibt doch keinen Sinn, weise mir etwas zu, aber ich bin konstant?! (also das zweite const in deinem MyRectangle operator=(const double d) const)



  • Dein Quellcode wäre leichter zu lesen, wenn du ihn mit den Bordmitteln hier formatieren würdest. Nutze bitte den Codeblock im Editor.



  • @wob Man hat manchmal Klassen, die mutable member haben. In dem Fall kann es sehr wohl, sein, dass man einen operator= in einer const Variante braucht.

    Hier auf jeden Fall nicht.



  • @Dafina-97
    Wenn du etwas nicht verstehst, so würde ich dir empfehlen den Code in eine schöne Form zu bringen und zu dokumentieren. Zum Beispiel:

    
    /**
    * \class MyRectangle
    * 
    * \brief Rechteck ...
    **/
    class MyRectangle
    {
    public:
        int x1 = 0;
        int x2 = 1;
        int y1 = 2;
        int y2 = 3;
    
    
    public:
        /**
          * \fn MyRectangle operator=(const double d) const
          *
          * \brief
          *     Liefert ein skaliertes Rechteck zurück.
          *
          * \todo
          *     Refactoring: Der Funktionsname ist sehr verwirrend bzw. mathematisch unsinnig
          *     da der Zuweisungsoperator überladen wird. Wenn ich beim programmieren a = 1 
          *     schreibe, so soll danach a 1 sein und nicht irgenteine Skalierung berechnen 
          *     und zurückgeben. BTW, wie könnte man das Ergebnis eigentlich nutzen?
          *     -> Der Name ist völlig unsinnig und muss drigend umbenannt werden. Ein Vorschlag: 
          *     MyRectangle CalcScaledRect(double d) const 
          *
          * \param d        [in] Skalierungsfaktor
          * 
          * \returns 
          *     Skaliertes Dreieck welches bei (x1, y1) beginnt. Die Breite / Höhe entspricht dem d-fachen des Originals.
          **/
        MyRectangle operator=(const double d) const
        {
            MyRectangle result = *this; // Hier sieht man die Merkwürdigkeit des oben überladenen Zuweisungsoperators. Hier ist die Zuweisung eine Zuweisung und keine Skalierungsberechnung oder Ähnliches.
            int tempx, tempy = 0;
    
            // In den folgenden zwei Zeilen wird anscheinend die skalierten Rechteckskoordinaten 
            // berechnet. Der Wert (result.x2 - result.x1) entspricht der Breite des Rechtecks.
            // Dieser wird mit d multipliziert und auf x1 addiert. Dadurch entsteht ein Rechteck
            // welches bei x1 beginnt und um den Faktor d breiter ist als das Original.
            tempx = ((result.x2 - result.x1) * d) + result.x1; // sieht nach Geradengleichung aus
            tempy = ((result.y2 - result.y1) * d) + result.y1;
            result.x2 = tempx; // Werte übernehmen, tempx und tempy sind eigentlich unnötig
            result.y2 = tempy;
            return result;
        }
    
    };
    
    int main()
    {
        MyRectangle r;
    
        r = 5;                      // Aufgabe: Was macht hier die Funktion? -> Debuggen 
        MyRectangle r2(r = 5.5);    // Aufgabe: Was macht hier die Funktion? -> Debuggen 
        return 0;
    }
    


  • @Martin-Richter sagte in Fragen zu Void draw:

    @wob Man hat manchmal Klassen, die mutable member haben. In dem Fall kann es sehr wohl, sein, dass man einen operator= in einer const Variante braucht.
    Hier auf jeden Fall nicht.

    Habe deine Begründung nicht verstanden. Auch wenn eine Klasse mutable Member hat, sollte der operator= doch normalerweise non-const sein. Die Idee der Zuweisung ist doch normalerweise, dass eben genau das Objekt links vom = geändert werden soll.

    (Klar kann man alles const machen und dann alle Member mutable, aber das ist doch nicht die Idee einer Zuweisung?! - und außerdem stiftest du bei @Dafina-97 bestimmt noch mehr Verwirrung)



  • @Martin-Richter sagte in Fragen zu Void draw:

    @wob Man hat manchmal Klassen, die mutable member haben. In dem Fall kann es sehr wohl, sein, dass man einen operator= in einer const Variante braucht.

    Das würde ich nur akzeptieren, wenn die Zuweisung keinen vom Anwender der Klasse beobachtbaren Effekt hat (höchstens private Member verändert) und sich die Klasse danach exakt so verhält, als hätte keine Zuweisung stattgefunden.

    Mir fällt es jedenfalls schwer, da einen Anwendungsfall zu konstruieren. Klar, sowas wie ein Mutex-Member kann durchaus wohlbegründet mutable sein und über const-Methoden verändert werden, aber die Zuweisung dürfte eben auch keinen anderen Member verändern, von dem der Anwender irgendwas mitbekommen könnte.

    Vielleicht einen speziellen null-Typen bei dem jede Operation auf diesem eine No-Op ist - sowas wie ein Null-Logger der alles ins Nirvana schickt, aber bei dem eben auch eine Zuweisung eine dieser Operationen ist? Dann frage ich mich allerdings warum keine Klasse ohne Daten-Member und mit leeren Member-Funktionen. Ein operator=() const - falls es denn wirklich einen sinnvollen Anwendungsfall dafür gibt - wäre jedenfalls ein derart exotischer Fall, dass man davon gerade als Anfänger nichts zu wissen braucht.



  • @Finnegan sagte in Fragen zu Void draw:

    @Martin-Richter sagte in Fragen zu Void draw:

    @wob Man hat manchmal Klassen, die mutable member haben. In dem Fall kann es sehr wohl, sein, dass man einen operator= in einer const Variante braucht.

    Das würde ich nur akzeptieren, wenn die Zuweisung keinen vom Anwender der Klasse beobachtbaren Effekt hat (höchstens private Member verändert) und sich die Klasse danach exakt so verhält, als hätte keine Zuweisung stattgefunden.

    Gebe ich Dir zu 100% recht. Das muss man sich genau überlegen, wie immer bei mutable Membern.

    Ich habe sogar einen Anwendungsfall:

    • Man hat eine komplexe Klasse, die auch ein "Logger"-Objekt unterstützt.
    • Den Logger darf man zuweisen, auch einem const Objekt.

    Hängt eben alles immer vom Design-Fall ab.



  • @Martin-Richter sagte in Fragen zu Void draw:

    Ich habe sogar einen Anwendungsfall:

    • Man hat eine komplexe Klasse, die auch ein "Logger"-Objekt unterstützt.
    • Den Logger darf man zuweisen, auch einem const Objekt.

    Hm... Finde ich schwierig, das gut zu finden.

    const KomplexObjekt ko = get_it_from_somewhere();
    Logger new_logger = give_me_a_logger();
    ko = new_logger;
    

    Das soll bei dir funktionieren? Ich finde das sehr verwirrend. Ich darf KomplexObjekt = LoggerObjekt schreiben und setze damit irgendeinen mutable Member?! Halte ich für Abuse des =-Operators.

    Ich würde eher akzeptieren (wenn unbedingt nötig, eigentlich lieber nicht):

    const KomplexObjekt ko = get_it_from_somewhere();
    Logger new_logger = give_me_a_logger();
    ko.set_logger(new_logger);
    

    Generell bin ich aber sowieso kein Freund von Mutable. Vielleicht in Ordnung für irgendeinen internen Cache. Aber doch nicht so wie hier. Wäre meine überzeugte Meinung.



  • @Martin-Richter
    Wieso muss bzw. soll man das über den Zuweisungsoperator machen? Wenn nur ein Teil des Objekts geändert wird, der nochdazu nichtmal zum beobachtbaren Zustand gehört, dann halte ich es für höchst verwirrend dafür den Zuweisungsoperator zu verwenden.


Anmelden zum Antworten