Ich versuche die konstante Referenz in C ++ zu verstehen und bin über dieses Problem gestolpert:
Wenn ich einer const int & amp; und dann den Wert des referenzierenden Double ändern, der Wert meiner int-Referenz bleibt konstant.
%Vor%Bei der Zuweisung von int wird der Wert geändert.
%Vor%Was ist der Grund für dieses Verhalten? Meine Vermutung ist, dass bei der Zuweisung von double die implizite Konvertierung zu int ein neues Objekt erzeugt und seine Referenz zugewiesen wird, ich kann sie jedoch nirgendwo finden.
Auch wenn es aussieht, ist ref
kein Verweis auf i
.
Ein Verweis auf int
kann nicht auf double
verweisen. Daher wird in der markierten Zeile eine Konvertierung von double
in int
ausgeführt und das Ergebnis der Konvertierung ist ein temporärer rvalue. Normalerweise werden sie zerstört, wenn der volle Ausdruck, in dem sie erstellt wurden, endet. Aber es gibt eine Regel in C ++, die es erlaubt, die Lebensdauer eines temporären zu verlängern, wenn es an einen Verweis auf const
gebunden ist. Es wird verlängert, bis die Referenz stirbt. Dafür reserviert der Compiler hinter den Kulissen tatsächlich etwas Speicher.
Die Zuweisung ändert das ursprüngliche Objekt i
, das unbenannte temporäre bleibt intakt.
Wenn Sie die double
in eine int
konvertieren, ist das Ergebnis ein rvalue vom Typ int
. Dieser temporäre Wert ist an eine konstante Referenzvariable gebunden, und somit wird die Lebensdauer des temporären Werts auf diejenige der Referenzvariablen erweitert. Das Ändern des ursprünglichen double
hat keine Auswirkung darauf.
Der Compiler kann Ihnen nur dann helfen, wenn Sie const
aus beiden Deklarationen entfernen und versuchen, die Code-Snippets zu kompilieren:
Dieser Code wird Kompilierungsfehler geben! Warum?
Aber dieser Code:
%Vor%wird kompiliert.
Wenn der erste Code fein kompiliert wird, wenn const
vorhanden ist, warum kompiliert er dann nicht (wenn const
nicht da ist)? Was passiert unter der Motorhaube?
Nun, der Grund ist, dass int&
ein Referenztyp ist, der sich auf ein Objekt vom Typ int
beziehen kann, nicht auf double
, also auf ein temporäres Objekt vom Typ int
wird aus dem Ausdruck i
erstellt (was double
ist), aber das temporäre Objekt kann nicht an int&
binden, daher gibt es Kompilierungsfehler , aber sobald Sie% co_de setzen % dort kompiliert es gut, weil ein temporäres Objekt vom Typ const
an int
binden kann.
Im zweiten Code passiert nichts - kein temporäres Objekt wird erstellt. Wenn Sie also const int&
auf i
setzen, ändert sich auch 20
im zweiten Fall (da es sich auf ref
bezieht), aber im ersten Fall, wenn Sie i
auf i
setzen, wird 20
ändert nicht , weil ref
nicht mehr auf ref
verweist - es bezieht sich eher auf das temporäre Objekt (das Sie nicht sind ) stark> wechselnd!). Das erklärt das Verhalten Ihrer Code-Snippets.
Ich hoffe, das hilft.
Abhängig von dem Compiler, den Sie verwenden, kann dieser Code auch einen Kompilierungsfehler ergeben.
Bei einem Compiler, der einen Fehler auslöst, würden Sie, wenn Sie ihn in (int &)
umwandeln, ein undefiniertes Verhalten sehen, da Sie ein int von der Position eines Doppels lesen.
Bei einem Compiler, der diese Zeile akzeptiert, rate ich am besten, eine temporäre Variable (einen R-Wert) zu erstellen und der int-Referenz zuzuweisen. Änderungen an der ursprünglichen Variable werden nicht in der Referenz berücksichtigt.
Stellen Sie sicher, dass der Quelldatentyp durch den Zieldatentyp dargestellt wird.