Главная » Просмотр файлов » B. Stroustrup - The C++ Programming Language

B. Stroustrup - The C++ Programming Language (794319), страница 48

Файл №794319 B. Stroustrup - The C++ Programming Language (B. Stroustrup - The C++ Programming Language) 48 страницаB. Stroustrup - The C++ Programming Language (794319) страница 482019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 48)

I return the result by non-const reference because theuser of a Map might very well want to modify the found value. For example:Section 7.7.1Lvalue References193int main() // count the number of occurrences of each word on input{Map<string,int> buf;for (string s; cin>>s;) ++buf[s];for (const auto& x : buf)cout << x.first << ": " << x.second << '\n';}Each time around, the input loop reads one word from the standard input stream cin into the string s(§4.3.2) and then updates the counter associated with it. Finally, the resulting table of differentwords in the input, each with its number of occurrences, is printed.

For example, given the inputaa bb bb aa aa bb aa aathis program will produceaa: 5bb: 3The range- for loop works for this becausestandard-library map.Mapdefinedbegin()andend(),just as is done for the7.7.2 Rvalue ReferencesThe basic idea of having more than one kind of reference is to support different uses of objects:• A non-const lvalue reference refers to an object, to which the user of the reference canwrite.• A const lvalue reference refers to a constant, which is immutable from the point of view ofthe user of the reference.• An rvalue reference refers to a temporary object, which the user of the reference can (andtypically will) modify, assuming that the object will never be used again.We want to know if a reference refers to a temporary, because if it does, we can sometimes turn anexpensive copy operation into a cheap move operation (§3.3.2, §17.1, §17.5.2).

An object (such asa string or a list) that is represented by a small descriptor pointing to a potentially huge amount ofinformation can be simply and cheaply moved if we know that the source isn’t going to be usedagain. The classic example is a return value where the compiler knows that a local variablereturned will never again be used (§3.3.2).An rvalue reference can bind to an rvalue, but not to an lvalue. In that, an rvalue reference isexactly opposite to an lvalue reference. For example:string var {"Cambridge"};string f();string& r1 {var};string& r2 {f()};string& r3 {"Princeton"};// lvalue reference, bind r1 to var (an lvalue)// lvalue reference, error : f() is an rvalue// lvalue reference, error : cannot bind to temporar y194Pointers, Arrays, and Referencesstring&& rr1 {f()};string&& rr2 {var};string&& rr3 {"Oxford"};Chapter 7// rvalue reference, fine: bind rr1 to rvalue (a temporar y)// rvalue reference, error : var is an lvalue// rr3 refers to a temporar y holding "Oxford"const string cr1& {"Harvard"}; // OK: make temporar y and bind to cr1The && declarator operator means ‘‘rvalue reference.’’ We do not use const rvalue references; mostof the benefits from using rvalue references involve writing to the object to which it refers.

Both aconst lvalue reference and an rvalue reference can bind to an rvalue. However, the purposes will befundamentally different:• We use rvalue references to implement a ‘‘destructive read’’ for optimization of what wouldotherwise have required a copy.• We use a const lvalue reference to prevent modification of an argument.An object referred to by an rvalue reference is accessed exactly like an object referred to by anlvalue reference or an ordinary variable name. For example:string f(string&& s){if (s.size())s[0] = toupper(s[0]);return s;}Sometimes, a programmer knows that an object won’t be used again, even though the compilerdoes not.

Consider:template<class T>swap(T& a, T& b)// "old-style swap"{T tmp {a}; // now we have two copies of aa = b;// now we have two copies of bb = tmp; // now we have two copies of tmp (aka a)}If T is a type for which it can be expensive to copy elements, such as string and vector, this swap()becomes an expensive operation. Note something curious: we didn’t want any copies at all; we justwanted to move the values of a, b, and tmp around. We can tell that to the compiler:template<class T>void swap(T& a, T& b)// "perfect swap" (almost){T tmp {static_cast<T&&>(a)}; // the initialization may write to aa = static_cast<T&&>(b);// the assignment may write to bb = static_cast<T&&>(tmp); // the assignment may write to tmp}The result value of static_cast<T&&>(x) is an rvalue of type T&& for x.

An operation that is optimized for rvalues can now use its optimization for x. In particular, if a type T has a move constructor (§3.3.2, §17.5.2) or a move assignment, it will be used. Consider vector:Section 7.7.2Rvalue References195template<class T> class vector {// ...vector(const vector& r); // copy constructor (copy r’s representation)vector(vector&& r);// move constructor ("steal" representation from r)};vector<string> s;vector<string> s2 {s};vector<string> s3 {s+"tail");// s is an lvalue, so use copy constructor// s+"tail" is an rvalue so pick move constructorThe use of static_cast in swap() is a bit verbose and slightly prone to mistyping, so the standardlibrary provides a move() function: move(x) means static_cast<X&&>(x) where X is the type of x.Given that, we can clean up the definition of swap() a bit:template<class T>void swap(T& a, T& b){T tmp {move(a)};a = move(b);b = move(tmp);}// "perfect swap" (almost)// move from a// move from b// move from tmpIn contrast to the original swap(), this latest version need not make any copies; it will use moveoperations whenever possible.Since move(x) does not move x (it simply produces an rvalue reference to x), it would have beenbetter if move() had been called rval(), but by now move() has been used for years.I deemed this swap() ‘‘almost perfect’’ because it will swap only lvalues.

Consider:void f(vector<int>& v){swap(v,vector<int>{1,2,3});// ...}// replace v’s elements with 1,2,3It is not uncommon to want to replace the contents of a container with some sort of default value,but this particular swap() cannot do that. A solution is to augment it by two overloads:template<class T> void swap(T&& a, T& b);template<class T> void swap(T& a, T&& b)Our example will be handled by that last version of swap(). The standard library takes a differentapproach by defining shrink_to_fit() and clear() for vector, string, etc. (§31.3.3) to handle the mostcommon cases of rvalue arguments to swap():void f(string& s, vector<int>& v){s.shrink_to_fit();// make s.capacity()==s.size()swap(s,string{s});// make s.capacity()==s.size()196Pointers, Arrays, and Referencesv.clear();swap(v.vector<int>{});v = {};Chapter 7// make v empty// make v empty// make v empty}Rvalue references can also be used to provide perfect forwarding (§23.5.2.1, §35.5.1).All standard-library containers provide move constructors and move assignment (§31.3.2).Also, their operations that insert new elements, such as insert() and push_back(), have versions thattake rvalue references.7.7.3 References to ReferencesIt you take a reference to a reference to a type, you get a reference to that type, rather than somekind of special reference to reference type.

But what kind of reference? Lvalue reference or rvaluereference? Consider:using rr_i = int&&;using lr_i = int&;using rr_rr_i = rr_i&&;using lr_rr_i = rr_i&;using rr_lr_i = lr_i&&;using lr_lr_i = lr_i&;// ‘‘int && &&’’ is an int&&// ‘‘int && &’’ is an int&// ‘‘int & &&’’ is an int&// ‘‘int & &’’ is an int&In other words, lvalue reference always wins. This makes sense: nothing we can do with types canchange the fact that an lvalue reference refers to an lvalue. This is sometimes known as referencecollapse.The syntax does not allowint && & r = i;Reference to reference can only happen as the result of an alias (§3.4.5, §6.5) or a template typeargument (§23.5.2.1).7.7.4 Pointers and ReferencesPointers and references are two mechanisms for referring to an object from different places in aprogram without copying.

We can show this similarity graphically:pp:&iirr:ii:1Each has its strengths and weaknesses.If you need to change which object to refer to, use a pointer. You can use =, +=, −=, ++, and −−to change the value of a pointer variable (§11.1.4). For example:Section 7.7.4Pointers and References197void fp(char∗ p){while (∗p)cout << ++∗p;}void fr(char& r){while (r)cout << ++r;// oops: increments the char referred to, not the reference// near-infinite loop!}void fr2(char& r){char∗ p = &r;// get a pointer to the object referred towhile (∗p)cout << ++∗p;}Conversely, if you want to be sure that a name always refers to the same object, use a reference.For example:template<class T> class Proxy {T& m;public:Proxy(T& mm) :m{mm} {}// ...};// Proxy refers to the object with which it is initializedtemplate<class T> class Handle { // Handle refers to its current objectT∗ m;public:Proxy(T∗ mm) :m{mm} {}void rebind(T∗ mm) { m = mm; }// ...};If you want to use a user-defined (overloaded) operator (§18.1) on something that refers to anobject, use a reference:Matrix operator+(const Matrix&, const Matrix&);Matrix operator−(const Matrix∗, const Matrix∗);// OK// error : no user-defined type argumentMatrix y, z;// ...Matrix x = y+z;// OKMatrix x2 = &y−&z; // error and uglyIt is not possible to (re)define an operator for a pair of built-in types, such as pointers (§18.2.3).198Pointers, Arrays, and ReferencesChapter 7If you want a collection of something that refers to an object, you must use a pointer:int x, y;string& a1[] = {x, y};string∗ a2[] = {&x, &y};vector<string&> s1 = {x , y};vector<string∗> s2 = {&x, &y};// error : array of references// OK// error : vector of references// OKOnce we leave the cases where C++ leaves no choice for the programmer, we enter the domain ofaesthetics.

Характеристики

Тип файла
PDF-файл
Размер
18,76 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6418
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее