Design Frage: Wann sollte eine Methode ihr Objekt verändern?



  • Hallo,

    ich hab (mal wieder) eine Frage bezüglich Klassendesign. Mal angenommen ich hab eine Matrix Klasse für mathematische Aufgaben: Sollte dann die an dem Matrix-Objekt aufgerufene Methode dieses verändern oder nicht? Also Beispiel:

    matrix1.transpose(); // Die Matrix matrix1 ist jetzt transponiert
    

    oder

    matrix2 = matrix1.transpose(); // Die Matrix matrix2 ist jetzt matrix1 transponiert, matrix 1 bleibt aber unverändert
    

    Was ist hier zu bevorzugen und warum? Wann sollte man den oberen Fall wählen, wann den unteren?

    Freue mich über input 🙂
    hs



  • Ich wähle Alternative C:

    auto mat2 = transposed(mat1);
    

    Nur wenn man das in-place irgendwie optimaler hinbekommt, würde ich noch einen Member ohne Rückgabe anbieten. Aber in-place transponieren ist hakeliger als man auf Anhieb denken würde...



  • decimad schrieb:

    Nur wenn man das in-place irgendwie optimaler hinbekommt, würde ich noch einen Member ohne Rückgabe anbieten. Aber in-place transponieren ist hakeliger als man auf Anhieb denken würde...

    Nicht wenn man einfach Indizes tauscht.



  • Letzteres ist flexibler, weil Du das Original behälst. Ersteres ist i.d.R. schneller und/oder verbraucht weniger Speicherplatz. Welches der beiden Designziele wichtiger ist, hängt von der Aufgabe ab.

    mfg Martin



  • Meine Faustregel, die sich bewährt hat:
    Memberfunktionen arbeiten inplace, freie Funktionen nicht.
    Im Zweifelsfall kannst du ja beides anbieten, wobei ich eher zu nicht-inplace tendiere. Mit move spart man sich auch Kopien.



  • In-Place sollte man schon anbieten, da es tatsächlich effizienter sein kann. Meist kann man dann die andere Version über In-Place implementieren.

    Die Frage ist eher, wie du die Funktionen benennst und ob du sie zu Memberfunktionen machst. Ein paar Möglichkeiten:

    m.transpose();
    m.transposeCopy();
    
    m.transpose();
    m.transposed();
    
    m.transposeInPlace();
    m.transpose();
    
    m.transpose();
    transposed(m);
    


  • Ich mag die Namen mit copy. Erinnert mich an die boost-string-replace-Funktionen. Zudem erwarte ich bei einer Matrix erstmal keine Kopie, wenn ich ihr sage "Transponier Dich, Du!"



  • Alles klar, danke für die vielen Antworten! Werd dann wohl tatsächlich jeweils zwei Methoden anbieten, das garantiert die größtmögliche Flexibilität.



  • Über Index-Tausch zu transponieren vergrößert die Matrix, erzeugt runtime-checks, und dort wo das unwichtig ist, also bei großen Matrizen, verändert es drastisch die Zugriffscharakteristik im Speicher. Da würde ich dann lieber eine move-transposed-Funktion anbieten, das aus einer column-major eine row-major matrix macht, vice versa... Ansonsten hängt man bei den Algorithmen dann und hat überall is_transposed in einem if-Konstrukt rumstehen und die Algorithmen zweimal implementiert.


Anmelden zum Antworten