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 transponiertoder
matrix2 = matrix1.transpose(); // Die Matrix matrix2 ist jetzt matrix1 transponiert, matrix 1 bleibt aber unverändertWas 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.