# 02 Лекция, rvalue-ссылки, move-семантика, xvalue, copy elision, lifetime extension (03.09.2022) > [TOC] ## Move и r-value До C++11 ```cpp #include <vector> #include <string> class str { private: char *data; size_t len; str(str const&); //copy str(str& prev): //move - нельзя сделать r-value data(prev.data), len(prev.len) { prev.data = nullptr; prev.len = 0; } }; int main () { std::vector<std::string> vec; std::string s; vec.push_back(s); str b; } ``` --- Отличие l-value и r-value ```c int main() { int a; //l-value int &b = a; //int &c = 42; error //r-value //int &&d = a; error int &&e = 42; } ``` --- Как надо: ```c class str { private: char *data; size_t len; str(str const&); //copy construct str(str &&) //move construct, r-value str& operator=(str const&); //copy operator str& operator=(str &&; //move operator, r-value }; ``` Как сделать move на локальную переменную: ```cpp int main() { str a(); str b(static_cast<str&&>(a)); //каст к r-value ссылке str b(move(a)); //тоже самое, только из стандартной библиотеки } ``` --- Нужно не забывать мувать обьекты внутри класса: ```cpp struct person { std::string name; person(std::string &&name) : name(std::move (name)) {} person(std::string name, std:: string surname) : name(std::move(name)) , name(std::move(surname)) {} } ``` **ИЛИ** Как надо принимать аргументы: ```cpp struct person { std::string name; std::string surname; person(std::string name, std::string surname) //принимает по значению : name(std::move(name)) , surname(std::move(surname)) {} } ``` **Делать копию или нет, в случае передачи по значению - выбирает вызывающая сторона.** --- Ошибка новичка: (пытаться избежать копирования там где его нет!) Норм: ```cpp std::string foo() { std::string res; //code return res; //копирования не будет! } ``` БРЕД: (уничтожается локальная переменная при выходке из функции) ```cpp std::string& foo() { std::string res; //code return res; } ``` БРЕД 2: (уничтожается локальная переменная при выходке из функции) ```cpp std::string&& foo() { std::string res; //code return std::move(res); } ``` --- ## l-value, r-value и x-value ![](https://i.imgur.com/uGqjOtd.jpg) ```cpp struct mytype{}; mytype prvalue(); //r-value записывает результат в память mytype& lvalue(); //l-value mytype&& xvalue(); //x-value void foo(mytype); void foo(mytype const&); void foo(mytype&&); mytype test() { foo(prvalue()); //r-value, mytype&& foo(lvalue()); //l-value, mytype const& foo(xvalue()); //x-value, mytype&& return prvalue(); //RVO return lvalue(); //non RVO return xvalue(); //NON RVO mytype const &ref = prvalue(); //r-value, life extension mytype const &lref = lvalue(); //l-value, no left extension mytype const &xref = xvalue(); //x-value, no left extension mytype &&ref1 = prvalue(); //r-value, life extension //mytype &&lref1 = lvalue(); //compilation error mytype &&xref1 = xvalue(); //x-value, no left extension } ``` # Оглавление > [TOC]