const member Funktion in Aufrufsequenz
-
Hallo Zusammen,
bin gerade über den C++ Primer 5th edition bei §7.3.2 p. 276.
Es geht darum, dass es nicht (immer) möglich ist, eine Aufrufsequenz zu realisieren, wenn eine member Funktion const ist.
Beispiel:
class Foo { public: const Foo& justRead() const; Foo& changeSth(); }; // Wo anders... fooObject.justRead().changeSth(); // Fehler!
Die Empfehlung lautet jetzt eine const und eine non-const Version der Funktion einzuführen:
class Foo { public: const Foo& justRead() const {doJustRead(); return *this;} Foo& justRead() (doJustRead(); return *this;} Foo& changeSth(); private: void doJustRead() const {...} }; // Wo anders... fooObject.justRead().changeSth(); // OK
Jetzt ist meine Frage, führe ich damit nicht das const welches justRead eigentlich bescheinigt nur zu lesen nicht ad absurdum? Klar auf einer const reference wird die const Funktion aufgerufen. Aber auf einer non-const Referenz eben nicht, sprich, die Methode die eigentlich nur lesen sollte kann jetzt prinzipiell alles machen.
Mir ist auch klar, dass man die Verkettung so anordnen könnte, dass zuerst geändert, dann gelesen wird.
Ich persönlich habe das const immer so interpretiert, dass es eine Zusicherung an den Aufrufer ist, dass der Objektzustand sich nicht ändert (zumindest nicht an der Schnittstelle [Stichwort mutable]).
Lange Rede kurzer Sinn, mich würde einfach mal eure Meinung zu diesem überladen einer const Funktion interessieren. Teilt ihr die Meinung, dass man es legitim ist, dass zu machen? Oder seht ihr das wie ich eher etwas kritisch weil die Schnittstelle damit doch etwas verwässert wird?
Viele Grüße!
-
Die Rückgabe einer const Foo& verursacht den Fehler im ersten Beispiel, nicht die constness der Funktion.
Versuch es mal so:
class Foo { public: Foo& justRead() const; Foo& changeSth(); }; // Wo anders... fooObject.justRead().changeSth(); // OK
-
@nurso
Damit führst duconst
ad absurdum. Da haste jetzt nicht wirklich drüber nachgedacht, oder?
-
Das Beispiel ohne Referenz auf Const lässt sich gar nicht ohne übersetzen, weil der Compiler einem hier (Dankenswerterweise) schon vorher zurechtweist.
Wieso man das
const
bei der Rückgabereferenz nicht weg lassen kann liegt daran, dassthis
bereitsconst
ist.Wir würden also eine nicht const referenz auf ein const objekt zurückgeben.
-
Naja man könnte es wegcasten, nur damit würde man eben den ganzen const Mechanismus aushebeln.
Die zwei Overloads sind schon OK. Man muss dann halt bei der Implementierung "brav" sein, und eben nix am internen State ändern. Sondern idealerweise einfach den const Overload aufrufen (ohne return) und danach ein eigenes return *this machen - was dann ja wieder non-const ist.
-
Einfach mal logisch betrachtet ist:
object.readOnly().change();
ein Widerspruch in sich.
Das würde bedeuten, eine Funktion, die dem Aufrufer garantiert, das Objekt nicht zu ändern, darf das Objekt einfach nicht ändern und die Aufrufsequenz ist nicht erlaubt.
Stellt sich mir die Frage: Welche Gründe, neben der "Datensicherheit" gibt es noch für eine solche const-Funktion? Performance?
temi
-
temi schrieb:
Einfach mal logisch betrachtet ist:
object.readOnly().change();
ein Widerspruch in sich.
Du bringst es auf den Punkt!
-
Hi Zusammen,
Belli schrieb:
temi schrieb:
Einfach mal logisch betrachtet ist:
object.readOnly().change();
ein Widerspruch in sich.
Du bringst es auf den Punkt!Das Beispiel ist natürlich etwas unglücklich
nehmen wir an, man hat eine Serielle Schnittstellen Klasse mit der man eine Befehlssequenz übertragen möchte.
SerialInterface.SetByte(1,0xf1).Send().SetByte(1,0xf2).Send().SetByte(1,0xf3).Send();
Von Send würde ich erwarten, dass es den inneren Zustand der Klasse nicht verändert, also const ist.
Aber ich möchte gar nicht so sehr auf einem Beispiel herum reiten als viel mehr darauf hinaus (ich denke hier herrscht Konsens), dass es etwas unglücklich ist, eine const Funktion mit einer Funktion zu überladen, die nicht const ist nur um solche Ketten zu ermöglichen.
Viele Grüße!
-
Ist dafür nicht
const_cast
geschaffen?
-
[...]nur um solche Ketten zu ermöglichen.
Solche Ketten willst du nicht haben, man.