Funktionsdeklaration mit &
-
const bedeutet dass es eine konstante Methode ist, die auf konstante Instanzen aufgerufen wird. Daher kann sie keine Referenz zurückgeben, sondern eine Kopie.
void foo(const deintyp& x) { x[1]; // const version } void bar(deintyp& x) { x[1]; // version ohne const }
-
Das mit dem &-Zeichen ist eine Referenz. das ist ein wichtiges und mächtiges Sprachkonstrukt, welches du unbedingt mal in einem Lehrbuch nachschlagen solltest. Kurze Erklärung was es hier macht: Im Fall ohne & wird eine Kopie des Wertes v[i] zurückgegeben. Im Falle mit dem &-Zeichen wird quasi v[i] selbst zurückgegeben. Das heißt man kann v[i] über den Funktionsaufruf ändern.
Die Sache mit dem const: Auch ein wichtiges Sprachkonstrukt. Die const-heit einer Funktion geht mit in die Überladungsauflösung ein. Das heißt man kann zwei gleichnamige Memberfunktionen haben die sich nur in ihrer constness unterscheiden. In einem Kontext wo man ein konstantes Objekt vorliegen hat wird dann die const-Variante genommen.
Hier sieht man auch den Unterschied mit der Referenz und der Kopie: Im falle mit dem const dürfte man natürlich nicht zulassen, dass der Wert v[i] über die Referenz geändert wird, denn das würde die constness verletzen. Daher wird eine Kopie zurückgegeben (eine Alternative wäre eine const Referenz). Im Falle der Rückgabe der Referenz kann die Funktion natürlich nicht const sein, da man über die Referenz v[i] ändern könnte.
-
Meine Güte, was macht ihr denn hier für komplexe Konstrukte aus einer const-Methode?
const hinter einer Methodendeklaration bedeutet schlicht, dass der this-Zeiger als Zeiger-auf-const (X const
übergeben wird. Ansonsten verhält sich so was wie jede andere überladene Funktion auch.Das geht übrigens auch mit volatile, obwohl ich dafür bisher keine Verwendung gefunden habe.
-
Das const ist hier wohl ein Kunstgriff (rate ich mal), damit sich die Signatur der beiden Funktionen unterscheidet.
Der Rückgabewert unterscheidet sich zwar zwischen den beiden Funktionen, aber der zählt nicht zur Signatur.
Ohne das const gäbe es einen Fehler beim Kompilieren ('function redefinition' oder sowas).
-
brotbernd schrieb:
void foo(const deintyp& x) { x[1]; // const version } void bar(deintyp& x) { x[1]; // version ohne const }Schönes Beispiel. Ein
x[1]=99;würde auch nur im zweiten Fall funktionieren, da im ersten Fall keine Referenz sondern nur ein Wert zurückkommt.
-
brotbernd schrieb:
const bedeutet dass es eine konstante Methode ist, die auf konstante Instanzen aufgerufen wird.
Genau genommen muss sie nicht unbedingt auf konstanten Instanzen aufgerufen werden. Wenn keine nicht-konstante Version vorhanden ist, wird die
const-qualifizierte Methode immer aufgerufen.brotbernd schrieb:
Daher kann sie keine Referenz zurückgeben, sondern eine Kopie.
Referenz geht schon. Wenn sie allerdings auf Membervariablen verweist, muss es sich um eine Const-Referenz (
const float&) handeln, was beifloatweniger sinnvoll als eine Kopie ist.antialias schrieb:
Das const ist hier wohl ein Kunstgriff (rate ich mal), damit sich die Signatur der beiden Funktionen unterscheidet.
Ja, allerdings ist das nicht nur Mittel zum Zweck oder Workaround, sondern gerade der Zweck selbst: Man will unterschiedliches Verhalten für konstante und veränderbare Objekte.
-
Stimmt...eben noch ein wenig gegoogelt und ne schöne Erklärung hier gefunden:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.12
-
Erstmal ein großes großes Dankeschön an alle Leute die geantwortet haben. Ich bin begeistert wie schnell die Antworten gekommen sind und wie hilfsbereit ihr seit. Ich werd dann mal weiter Fachbücher lesen. Ich werde mich hier auf jeden Fall registrieren und in Zukunft vielleicht ganz interessante Projekte herzeigen können.
-
@seldon
volatile in der Methodendeklarationint getVal(void) volatile;bewirkt, dass der this-Zeiger volatile behandelt wird und damit der Compiler eine Spezielle Zugriffssemantik beachtet. (s. Standard Kap 9.3.2)Das kann, vermute ich, beim Multithreading hilfreich sein, wenn man Locks o.ä. mit eine Klasse realisieren will. Ein konkretes Beispiel kann ich Dir im Moment aber auch nicht liefern.
-
ogni42 schrieb:
@seldon
volatile in der Methodendeklarationint getVal(void) volatile;bewirkt, dass der this-Zeiger volatile behandelt wird und damit der Compiler eine Spezielle Zugriffssemantik beachtet. (s. Standard Kap 9.3.2)Das kann, vermute ich, beim Multithreading hilfreich sein, wenn man Locks o.ä. mit eine Klasse realisieren will. Ein konkretes Beispiel kann ich Dir im Moment aber auch nicht liefern.
Andrei Alexandrescu hat hier mal ein Beispiel gebracht. Allerdings ist das nicht wirklich so nützlich, wie es aussehen mag. Zudem bewegt man sich dabei doch eher in einer Grauzone des Standards, denn die Semantik von volatile mit Objekten, die keine primtiven Typen oder Aggregate davon sind, ist nicht wirklich gut spezifiziert.