C++ - const Mitglieder / return-const int& vs return int
Was meinen wir mit den C++ - Linien? Gibt es alternative Möglichkeiten, um Sie zu schreiben?
const int& a() const;
int getA() const;
Dank.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese beiden sind zwei mögliche Signaturen für eine member-Funktion in einer Klasse, verspricht nicht zu ändern, das Objekt selbst. Im ersten Fall wird es wieder eine Konstante Referenz auf einen integer (ggf. ein member-Attribut), der Verweis wird
const
bedeutet, dass der Anrufer nicht in der Lage, es zu benutzen, ändern Sie das Attribut internal zu. Der zweite Fall, es gibt einen integer-Wert.Gibt es leichte Unterschiede in der Semantik, aber in den meisten Fällen werden Sie nicht sein, wichtig ist, sollten Sie in zwei Funktionen zu erhalten einen Wert. Für einen Fall, wo es macht einen Unterschied sehen:
Die Zeile gekennzeichnet mit [2] verwendet eine seltsam Merkmal der Sprache durch, die wenn Sie erhalten einen Konstante Referenz zu einem r-Wert (temporäre) der compiler binden, die vorübergehend auf den Bezug und lebendig zu halten, bis die Referenz den Gültigkeitsbereich verlässt (im Grunde dreht sich die r-Wert temporär in eine versteckte variable und bindet den Verweis darauf).
Ich Hinzugefügt, dass die Linie zu explizit, dass der Unterschied im Verhalten ist nicht durch das empfangende Ende
main
eine Kopie der Aufrechterhaltung einer Referenz, sondern (auch um genau zu sein) durch die Unterschrift des Accessors.Beides sind gleichwertige Möglichkeiten, das gleiche zu erreichen:
Sind Sie wieder einen Wert. Die const auf der rechten Seite der methodenkopf ist eine Bemerkung, die Funktionen getA() und() nicht ändern, das Objekt, welches Sie ausführen (die versteckten diesen parameter). Dies ist wichtig zur compile-Zeit, da es bedeutet, dass zusätzliche überprüfungen berücksichtigt werden, während der Kompilierung. Zur Laufzeit gibt es keinen Unterschied zwischen denen, die oben beschriebene Funktion und diese:
Jedoch die großen Vorteile der Erweiterung der überprüfung der Fähigkeiten des Compilers (nichts wird geändert, wenn Sie nicht erwarten, dass es passieren wird) sind offensichtlich lohnt sich die extra const.
Den zweiten Teil zu kümmern, sind die Rückgabe-Typen für beide Funktionen, das steht für die Haupt Unterschied zwischen Ihnen, und wahrscheinlich sind die motivation der Frage. Lasst uns das Thema wechseln, um eine andere Funktion:
Hier, ist der Rückgabewert wird wahrscheinlich das name-Attribut aus der Klasse. Die Rücksendung wird von dem Wert, was bedeutet, dass eine Kopie das Attribut wird erstellt, wenn die Rückgabe von dieser Methode. Dies kann ein Problem sein, wenn die Zeichenfolge ist groß und Sie bewegen eine Menge von strings durch den Wert in der Anwendung. Dann geschieht es, um die return-by-reference-Mechanismus, die verspricht, kein kopieren:
Dies ist eigentlich sehr interessant: wir sind der Rückgabe einer Referenz zu, anstatt eine Kopie des Objekts. Eine Referenz ist ähnlich wie ein Zeiger, so haben Sie zu kopieren, sondern nur einen Zeiger (4 bytes in einem 32-bit system) anstatt des gesamten Objekts.
Dies ist vielversprechend. Jedoch, es wird nicht mal kompilieren. Das kompilieren wird sich beschweren, dass Sie wieder eine Referenz, während Sie versprach die Methode const, und daher das Objekt wird ausgeführt, über die nicht geändert werden sollte. Dieser code würde es erlauben, illegale Vorgänge passieren:
Deshalb die const für die Rückkehr zu geben scheint, wie eine neue attraktive option, die das problem lösen. Eine Konstante Referenz wird nicht zulassen, dass änderungen an dem Objekt, es zeigt auf, mit:
Wird es jetzt kompilieren, während die bisherigen, bösartigen code nicht.
Lassen Sie uns nun zurück zu unserem problem:
Zweite ist ein return-by-value, was bedeutet, dass die int (4 bytes) kopiert werden auf die Rückkehr. Das erste bedeutet, dass eine Konstante Referenz auf ein int (4 Byte) zurückgegeben werden. Wie es kann gesehen werden, es gibt keine performance-Vorteil in diesem Fall für den Einsatz von return-by-reference statt return-by-value.
Als Faustregel gilt, Rückgabe von const-Referenz immer sicher ist, es wird nie mehr teurer als return-Wert.
int const& ri = ...;
Rücksendung der Referenz bedeutet, dass Sie die Gefahr, dass eine dangling reference; Rückgabe der Wert nicht.int
, dann die Menge der Arbeit ist gleichwertig, aber nicht Faktor in der Kunden Mühe zu Folgen, der Verweis und Lesen Sie den Wert ab....a()
gibt eine const-Referenz auf einint
.const
modifier am Ende bedeutet, dass Sie nicht ändern Sie den Status des Objekts abgerufen.Gleiche wie die obige Beschreibung, außer, dass der Rückgabetyp ist
int
muss eine Kopie der variable zurückgegeben, wenn erfasst.Was gemeint ist, wenn gesagt, nicht ändern der Zustand des Objekts?
Ebenfalls, Konstante Methoden nicht zurück-member-Variablen von nicht-const-Referenz.
to a int
. Ich glaube, es lohnt sich auch zu erwähnen, übermutable members
.nicht ändern der Zustand des Objekts ist Sie aufgerufen, mit Ausnahme der veränderlichen Mitglieder.const_cast
auch 😉const
.Der entscheidende Unterschied ist, dass:
getA()
gibt einint
Daten-Wert, der dann verwendet werden kann, indem der Anrufer völlig unabhängig von jedem anderen Teil des Programmsa()
gibt einen Verweis auf einigeint
dassa()
wählt:int x = a()
"samples", die den int-Wert zu diesem Zeitpunkt, und ist logisch äquivalent zuint x = getA()
const int& x = a()
speichert eine Referenz auf die variable zurückgegeben, die von a()!Speichern von Referenzen nicht immer das tun, was Sie erwarten oder wollen
die GUTE: der compiler ist intelligent genug, um eine Kopie der Variablen, wenn es nur temporär war /literal (z.B.
const int& x = a()
,const int& a() { return 3; }
)den GUTEN oder SCHLECHT? (je nachdem, ob es Sinn macht, in der app): jedes mal, wenn der Wert der
x
ist später zu Lesen, das Programm kann (versuchen zu) Lesen Sie ihn von der original -int
variable, diea()
intern zurückgegeben: wenn die variable, die den Wert geändert hat, dann wird der Wert vonx
wird sich auch ändern. ("möglicherweise" weil die Optimierungstool können dies vermeiden, wenn der Wert wäre ja eh der gleiche)den HÄSSLICH: wenn der Speicher an dieser Adresse nicht mehr speichern, die variable (z.B. war es in
new
ed Arbeitsspeicher, der seitdelete
d), dann versuchen zu Lesen, den Wert vonx
führen kann, dass ein unvorhersehbaren Wert oder Absturz der Anwendung (wenn die Speicher-Adresse ist nicht mehr lesbar).Beide
a()
undgetA()
sind member-Funktionen einer Klasse; wir wissen dies, weil nur member-Funktionen könnenconst
, die technisch zeigt Sie nicht ändern können, nichtmutable
Mitglieder-Daten ohne Guss -, Weg Ihre constness, aber die Absicht, die hinter dieser Einschränkung ist, dass Sie nicht ändern Sie die Anrufer-beobachtbaren Wert eines Objekts; änderbaren Daten werden in der Regel für caching, debugging trace etc..Können wir cast zurückgegebene Referenz auf Zeiger, also theoretisch macht es mehr info zur Verfügung (Adresse und Wert) als die Rückkehr einer Kopie (Wert).
Und es ist möglich zu hacken const ref zu veränderlich mit const_cast.
Compiler wird versuchen, sich mit dem Wert von original-register, Adresse oder wörtliche sowieso.
Alternative Wege für das Ziel? Um sicherzustellen, dass der Aufenthalt ständig korrigieren würde nicht fügen Sie zusätzliche Arbeit. Für const-reference und const-ich finde CR & CN-Makros hilfreich.
Nebeneffekt ist, dass die Erklärungen kürzer und wie die Linien werden kürzer, die Anzahl der Linien verringert sich ebenfalls. Frage des Geschmacks tho... Aber wenn kombiniert mit DMAP makro, es scheint um einen Vorteil zu haben.
vs
Ohne auto und mit der Verwendung von Iteratoren im Beispiel würde zeigen, mehr als 333% Unterschied.