Rvalue- og Lvalue-referencer
Stryg for at vise menuen
Begreberne lvalue og rvalue bruges til at klassificere udtryk i to typer: dem, der har en stabil placering i hukommelsen, og dem, der er midlertidige.
En lvalue (left value) er et udtryk, der refererer til en specifik placering i hukommelsen. Kort sagt er det en variabel med et navn, som kan ændres.
int x = 10;
Her er x en lvalue, fordi den har et navn, eksisterer i hukommelsen, og dens værdi kan ændres (x = 20).
En rvalue (right value) er en midlertidig værdi, der ikke har sit eget navn og kun eksisterer under evalueringen af et udtryk.
10
x + 5
int y = x + 5;
Her er x + 5 en rvalue, fordi det blot er resultatet af en beregning, ikke lagret som et separat objekt, og kan ikke ændres direkte.
Simpel idé:
- lvalue: noget med et navn og en hukommelsesadresse (en variabel);
- rvalue: et midlertidigt resultat (en værdi eller et udtryk).
Midlertidige værdier
En midlertidig værdi er et kortvarigt, mellemliggende resultat skabt under evalueringen af et udtryk.
rvalue.h
12345678// `(27 + 6 + 3 + 2)` is a tempopary value int sum = 27 + 6 + 3 + 2; // `static_cast<float>(sum)` is a tempopary value float avarage = static_cast<float>(sum) / count; // std::max(7, 9) will return a tempopary value int largest = std::max(7, 9);
Midlertidige værdier håndteres automatisk af compileren og eksisterer kun i varigheden af det udtryk eller den operation, hvor de er oprettet. Derefter bliver de typisk kasseret, og resultatet gemmes i målvariablen eller bruges efter behov.
Flyttesemantik
En rvalue-reference angives med dobbelt ampersand (&&).
Den eneste forskel mellem en lvalue- og en rvalue-reference er, at en rvalue kan bindes til et midlertidigt objekt, mens en lvalue-reference ikke kan.
int&& ref_value = 5 * 5;
Brug af en rvalue-reference i denne sammenhæng er muligvis ikke særlig praktisk, da der ikke er nogen fordel ved at bruge en rvalue-reference til et simpelt literal.
En kombination af lvalue- og rvalue-referencer anvendes til at understøtte move-semantik, hvilket muliggør overførsel af ressourcer fra ét objekt til et andet uden unødvendig kopiering. Se eksemplet nedenfor:
swap.h
123456std::string swap(std::string& a, std::string& b) { std::string tmp(a); // We have two copies of string `a` a = b; // Now we have two copies of string `b` b = tmp; // And now we have two copies of string `tmp` }
Men vi har ikke brug for kopier af a eller b. Vi ønskede blot at bytte dem. Lad os prøve igen.
main.cpp
1234567891011121314151617181920212223#include <iostream> void swap(std::string &a, std::string &b) { // Move the content of a into temp std::string temp(std::move(a)); // Move the content of b into a a = std::move(b); // Move the content of temp into b b = std::move(temp); } int main() { std::string a = "Hello\n"; std::string b = "Bye\n"; swap(a, b); std::cout << a << b; }
std::move(): omdanner en lvalue til en rvalue reference, muliggør move-semantik og overførsel af ejerskab uden kopiering.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat