Designfrage: Setter -> return *this?
-
Was meint ihr?
Sollte man bei jedem Setter das Objekt als Referenz wieder zurückgeben?
class myClass { std::string title; public: myClass& setTitle(const std::string&); };Schlechter Stil? Perfomanceverlust? Andere Gründe?
-
Geschmackssache.
Ich persönlich würde das ablehnen, denn es verleihtet sehr zu unübersichtlichen Konstrukten wie:
obj.setTitle("Foo").setDescription("Bar").setAge(15);
-
nein, sollte man nicht.
sollte aber keine (performance-)nachteile haben
-
wofür sollte das denn gut sein?
m.setTitle("hallo").setTitle("hallo welt");
-
warum sollte man das tun?
-
Das nennt man Function Chaining. Das hat den Vorteil, dass man nicht schreiben muss:
myClass.setBla(); myClass.setBlub(); myClass.setFoo();Sondern:
myClass.setBla().setBlub().setFoo();
-
...... schrieb:
Das nennt man Function Chaining. Das hat den Vorteil, dass man nicht schreiben muss:
Ob man dies als Vorteil sehen kann?
Ich persönlich bevorzuge einen Funktionsaufruf pro Zeile. Aber ist sicherlich auch Geschmacksache.Grüssli
-
Dravere schrieb:
...... schrieb:
Das nennt man Function Chaining. Das hat den Vorteil, dass man nicht schreiben muss:
Ob man dies als Vorteil sehen kann?
Ich persönlich bevorzuge einen Funktionsaufruf pro Zeile. Aber ist sicherlich auch Geschmacksache.Grüssli
Wie immer, gibt es immer Vor- und Nachteile. Es gibt Situationen, da machen solche Konstrukte Sinn.
myList.Add("Bla") .Add("Blub") .Add("Foo");Andererseits gibts natürlich auch massive Nachteile. Beispielsweise ist das Debugging solcher Ketten nicht sonderlich schön.
Auch kann die Lesbarkeit stark abnehmen, wenn man es übertreibt. Letzendlich ist aber auch std::cout eine Kette von Befehlen und daher nichts anderes. Das Konzept ist das gleiche - wo es Sinn macht, kann man darüber nachdenken.Man muss natürlich garantieren können, dass immer ein gültiges Objekt zurückgegeben wird. Ansonsten crasht natürlich alles.
-
Das von Janjan gebrachte Beispiel, was als Beispiel für unleserlichen Code gedacht war, empfinde ich übrigens als sehr leserlich und auf den ersten Blick verstädnlich.
-
Mir fällt da immer wieder SQL als Beispiel ein:
sql_ressource sql("www.my_sql_server.com"); std::vector<std::string> result = sql.select("*").from("users").where("client_id").equals(45).asc();
-
...... schrieb:
Wie immer, gibt es immer Vor- und Nachteile. Es gibt Situationen, da machen solche Konstrukte Sinn.
myList.Add("Bla") .Add("Blub") .Add("Foo");Ad aCTa schrieb:
Mir fällt da immer wieder SQL als Beispiel ein:
sql_ressource sql("www.my_sql_server.com"); std::vector<std::string> result = sql.select("*").from("users").where("client_id").equals(45).asc();Und beide Beispiele sind nicht treffend, da es hier eindeutig um Setter geht.
-
Ad aCTa schrieb:
Mir fällt da immer wieder SQL als Beispiel ein:
sql_ressource sql("www.my_sql_server.com"); std::vector<std::string> result = sql.select("*").from("users").where("client_id").equals(45).asc();Hi,
darf ich fragen aus welchem wrapper oder gar library/framework der Ausschnitt stammt.
Sieht nämlich ganz interessant aus.
Gruß Gate.
-
Gate schrieb:
Ad aCTa schrieb:
Mir fällt da immer wieder SQL als Beispiel ein:
sql_ressource sql("www.my_sql_server.com"); std::vector<std::string> result = sql.select("*").from("users").where("client_id").equals(45).asc();Hi,
darf ich fragen aus welchem wrapper oder gar library/framework der Ausschnitt stammt.
Sieht nämlich ganz interessant aus.
Gruß Gate.Ja, vor allem wenn man sich die Alternative anschaut, so einen SQL-String selber tippen zu müssen. Ich habs eben Testhalber für obige Abfrage mal gemacht und war überrascht.
-
Wie sieht dann sowas aus?
select name from employee where employeeID not in (select employeeID from assignment)
-
hhhhmmmm schrieb:
Wie sieht dann sowas aus?
select name from employee where employeeID not in (select employeeID from assignment)Vielleicht
select("name").from("employee").where("employeeID").notIN(sql.select("employeeED").from("assignment"));
-
Es könnte so aussehen.
sql.select("name") .from("employee") .where("employeeID").notin() .select("employeeID") .from("assignment")
-
Verhinder der Compiler dann sowas?
sql.where("dfs").select("*").equal("dsfsfs").from("f");Oder wird das sogar noch "richtig" ausgeführt?
-
hhhhmmmm schrieb:
Verhinder der Compiler dann sowas?
sql.where("dfs").select("*").equal("dsfsfs").from("f");Oder wird das sogar noch "richtig" ausgeführt?
Wie soll der Compiler es verhindern? Es sind nur Strings. Wenn es falsch Information kommt es dann zur ein Fehler.
-
hhhhmmmm schrieb:
Verhinder der Compiler dann sowas?
sql.where("dfs").select("*").equal("dsfsfs").from("f");Oder wird das sogar noch "richtig" ausgeführt?
Der Biblitheksschreiber kann es verhindern, muß es aber nicht verhindern.
Normalerweise wird er es verhindern mit den selben Mitteln mit denen er zum Beispiel vergessene From-Clauses verhindert.
-
Naja, wenn es einen Compileerror geben würde, wäre es natürlich schon praktisch, aber dann müsste select() nicht sql_ressource sondern was anderes zurück geben und das könnte sehr aufwendig werden für den Biblitheksschreiber. Man kann natürlich auch zur Laufzeit eine Exception werfen, aber dann kann ich das Statement auch so hinschreiben.
-
Mit genügend Aufwand, kann man das durchaus schaffen
