Der perfekte Setter/Getter
-
Ok, das war ein simples Beispiel, ich sollte mir angewöhnen kompliziertere zu posten. Jetzt stell dir mal vor man möchte noch Callbacks aufrufen oder die Werte validieren können.
-
Dann wird wir bestimmt ein besserer Name einfallen für sowas. Set drückt für mich aus:
some_member = some_value;
get drückt für mich aus:
return some_member;
Sowas ist Blödsinn.
-
const double& GetMyDouble() const
: Nein, so nicht. Stell dir mal vor, du stellst mal um und willst den Wert mal aus einer Datenbank holen, was für eine Referenz übergibst du dann? Lieber den blanken Wert.void setMyDouble(const double& myDouble)
: Fast. Perconst T&
zu übergeben macht bei komplizierteren Objekten Sinn, bei einem double nicht. Man will das Kopieren ersparen, aber Indirektionen kosten auch.
-
In beiden Fällen verlierst du Performance, weil du aktiv Compileroptimierungen verhinderst und stattdessen Indirektionen einbaust. Ganz besonders beim Rückgabewert ist es dem Compiler ausdrücklich erlaubt die Kopie weg zu optimieren, selbst dann wenn dadurch die Semantik des Programms geändert wird. Und auch Call by value kann unter gewissen Umstanden schneller sein als Call by reference. Ein Fall wird hier beschrieben:
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Der andere ist, wenn du durch das call by reference einfach keinen Gewinn hast: Du übergibst hier eine double Referenz, welche intern irgendwie als Pointer gebaut werden muss. Das sind 64-Bit Pointerübergabe und eine Pointerindirektion bei jeder Benutzung der Variablen, anstatt einfach direkt den double zu kopieren der auch 64-Bit groß wäre und man dann gar keine Indirektion hätte.(Alle Größenangaben von typischen modernen Systemen)
-
Ist ja interessant. Da will man das Programm optimieren und macht doch alles falsch.
Für primitive Typen wie boolean, double, int usw. wäre also eher soetwas angebracht:class MyClass { public: MyClass(): myDouble(42) { } const double GetMyDouble() const { return myDouble; } void setMyDouble(const double myDouble) { this->myDouble = myDouble; } private: double myDouble; };
Die const sind aber so in Ordnung?
Wie schaut das ganze nun aber aus, wenn ich für die primitiven Typen eigene Wrapper-Klassen Boolean, Double, Integer usw. habe. Wäre hier Call-by-Value trotzdem noch schneller.
Und wie sieht das bei z.B. einem solchen Color-Object ausclass Color { public: Color(); ... protected: unsigned char r; unsigned char g; unsigned char b; unsigned char a; };
Sollte man hier dann die Referenz übergeben?
-
StellerFragen schrieb:
Die const sind aber so in Ordnung?
Nein, gar nicht. Lass sie weg, sie bringen nichts.
Generell kannst du ein paar Byte kleine Objekte als Wert übergeben, z.B. auch Iteratoren. Sobald eine Klasse viel speichert (z.B. Container), übergib ihre Instanzen als Referenz. Im Zweifelsfall, sollte es tatsächlich eine Rolle spielen, nimmst du einen Profiler zur Hand.
-
@314159265358979:
Wenn setter und getter Blödsinn sind, dann waren die Leute die C# definiert haben wohl alle permanent betrunken, hm?@StellerFragen:
Top-level const sind bei Parametern unnötig/sinnlos, das hat Nexus schon geschrieben.
Was dein Color-Objekt angeht: ich würde sagen das ist grenzwertig. Wenn die Definition des Setters inline ist, ist es aber halb so wild: der Compiler kann dann trotzdem gut optimieren. Mit oder ohne Referenz.
-
StellerFragen schrieb:
Ist ja interessant. Da will man das Programm optimieren und macht doch alles falsch.
Es gibt sogar einen Namen dafür: Premature Optimizing.
-
loks schrieb:
StellerFragen schrieb:
Ist ja interessant. Da will man das Programm optimieren und macht doch alles falsch.
Es gibt sogar einen Namen dafür: Premature Optimizing.
Nein, es ist einfach nur falsche Optimierung. Premature wäre die, die Programmkomplexität erzeugt, die im Weiteren dafür sorgt, daß das Programm kaputt geht. Und die in so früher Phase noch ganz unnötig wäre.
Sich die passenden Rückgaben zu überlegen, also mal den Links folgen und hier by value zu bevorzugen, paßt durchaus in diese frühe Phase.
-
hustbaer schrieb:
@314159265358979:
Wenn setter und getter Blödsinn sind, dann waren die Leute die C# definiert haben wohl alle permanent betrunken, hm?Sieht so aus, wenn man sich alleine die Naming Convention ansieht.