Rvalue- ja Lvalue-viittaukset
Pyyhkäise näyttääksesi valikon
Käsitteet lvalue ja rvalue luokittelevat lausekkeet kahteen tyyppiin: niihin, joilla on pysyvä sijainti muistissa, ja niihin, jotka ovat väliaikaisia.
lvalue (vasemmanpuoleinen arvo) on lauseke, joka viittaa tiettyyn muistipaikkaan. Yksinkertaisesti sanottuna se on nimetty muuttuja, jota voidaan muokata.
int x = 10;
Tässä x on lvalue, koska sillä on nimi, se sijaitsee muistissa ja sen arvoa voidaan muuttaa (x = 20).
rvalue (oikeanpuoleinen arvo) on väliaikainen arvo, jolla ei ole omaa nimeä ja joka on olemassa vain lausekkeen arvioinnin ajan.
10
x + 5
int y = x + 5;
Tässä x + 5 on rvalue, koska se on vain laskennan tulos, jota ei tallenneta erillisenä oliona eikä sitä voi muuttaa suoraan.
Yksinkertainen ajatus:
- lvalue: nimetty ja muistiosoitteellinen (muuttuja);
- rvalue: väliaikainen tulos (arvo tai lauseke).
Väliaikaiset arvot
Väliaikainen arvo on lyhytikäinen, välimuotoinen tulos, joka syntyy lausekkeen arvioinnin aikana.
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);
Väliaikaiset arvot hallitaan automaattisesti kääntäjän toimesta, ja ne ovat olemassa vain sen lausekkeen tai operaation ajan, jossa ne luodaan. Tämän jälkeen ne yleensä poistetaan, ja tulos tallennetaan kohdemuuttujaan tai käytetään tarpeen mukaan.
Siirtosemanttiikka
Rvalue-viittaus merkitään kaksois-et-merkinnällä (&&).
Ainoa ero lvalue- ja rvalue-viittauksen välillä on, että rvalue voidaan sitoa väliaikaiseen olioon, kun taas lvalue-viittausta ei voida.
int&& ref_value = 5 * 5;
Rvalue-viittauksen käyttäminen tässä yhteydessä ei välttämättä ole kovin käytännöllistä, sillä yksinkertaiselle literaalille rvalue-viittauksesta ei ole hyötyä.
Lvalue- ja rvalue-viitteiden yhdistelmää käytetään tukemaan siirtosemanttiikkaa, mikä mahdollistaa resurssien siirtämisen objektista toiseen ilman turhaa kopiointia. Katso alla oleva esimerkki:
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` }
Mutta emme tarvitse kopioita muuttujista a tai b. Halusimme vain vaihtaa niiden arvot keskenään. Yritetään uudelleen.
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(): muuntaa lvalue-viitteen rvalue-viitteeksi, mahdollistaen siirtosemanttiikan ja omistajuuden siirron ilman kopiointia.
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme