C++/Przenoszenie wartości

Z Wikibooks, biblioteki wolnych podręczników.
< C++

W C++ zmienne są klasyfikowane na podstawie ich l-wartości i r-wartości. Lwartości to obiekty, które mają identyfikowalny adres pamięci, podczas gdy wartości r to obiekty tymczasowe, które nie mają identyfikowalnego adresu pamięci. Koncepcja odwołań r-wartości została wprowadzona w języku C++ 11 w celu ułatwienia bardziej wydajnego transferu wartości i konstruowania obiektów.

W tradycyjnym C++ jedynym sposobem przekazania obiektu do funkcji było przekazanie go przez wartość lub wskaźnik. Przekazywanie przez wartość tworzy kopię obiektu, co może być kosztowne pod względem czasu i zużycia pamięci. Przekazywanie przez wskaźnik wymaga dodatkowych operacji alokacji pamięci i cofania alokacji, co również może mieć wpływ na wydajność.

Dzięki referencjom rvalue wprowadzono nowy sposób przekazywania obiektów, który pozwala na bardziej efektywne przekazywanie wartości. Odniesienie r-wartości to odniesienie, które może wiązać się tylko z r-wartościami, co oznacza, że można go używać tylko do odwoływania się do obiektów tymczasowych, które mają zostać zniszczone lub przeniesione. Składnia służąca do definiowania odniesienia r-wartości polega na użyciu podwójnego operatora ampersand (&&).

Rozważ następujący przykład:

void foo(std::string&& str) {
   // zrób coś z str
}

int main() {
   std::string s = "Witaj, świecie!";
   foo(std::move(s)); // przenieś s do foo
   zwróć 0;
}

W tym przykładzie definiujemy funkcję foo, która przyjmuje odwołanie rvalue do obiektu std::string. W funkcji main tworzymy obiekt std::string s, a następnie przekazujemy go do foo za pomocą funkcji std::move, która konwertuje s na odwołanie do wartości.

Kiedy s jest przekazywane do foo, jest raczej przenoszone niż kopiowane. Oznacza to, że własność s jest przenoszona na foo, a pamięć, która była wcześniej używana przez s, jest teraz własnością foo. To przeniesienie własności może być bardziej wydajne niż kopiowanie całego obiektu, zwłaszcza w przypadku dużych lub złożonych obiektów.

Oprócz poprawy wydajności odniesienia rvalue mogą również służyć do włączania semantyki przenoszenia. Semantyka przenoszenia pozwala na wydajniejsze konstruowanie obiektów, umożliwiając tworzenie obiektów z obiektów tymczasowych bez tworzenia kopii. Semantyka przenoszenia jest szczególnie przydatna w przypadku obiektów, których kopiowanie jest kosztowne, na przykład zawierających duże ilości danych.