Стенли Липпман - Язык программирования C++. Пятое издание

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Язык программирования C++. Пятое издание"
Описание и краткое содержание "Язык программирования C++. Пятое издание" читать бесплатно онлайн.
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под стандарт С++11. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман работал старшим консультантом в Jet Propulsion Laboratory, архитектором группы Visual С++ корпорации Microsoft, техническим сотрудником Bell Laboratories и главным инженером- программистом по анимации в кинокомпаниях Disney, DreamWorks, Pixar и PDI.
Жози Лажойе, работающий ныне в кинокомпании Pixar, был членом канадской группы разработчиков компилятора C/C++ корпорации IBM, а также возглавлял рабочую группу базового языка С++ в составе международной организации по стандартизации ANSI/ISO.
Барбара Э. Му имеет почти тридцатилетний опыт программирования. На протяжении пятнадцати лет она работала в компании AT&T, сотрудничая с Бьярне Страуструпом, автором языка С++, и несколько лет руководила группой разработчиков С++.
• Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Деструктор вызывает функцию free():
StrVec::~StrVec() { free(); }
Оператор присвоения копии вызывает функцию alloc_n_copy() прежде, чем освободить существующие элементы. Это защищает от копирования в себя самого:
StrVec &StrVec::operator=(const StrVec &rhs) {
// вызов alloc_n_copy() для резервирования точно такого количества
// элементов, как в rhs
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
Подобно конструктору копий, оператор присвоения копии использует значения, возвращенные функцией alloc_n_copy(), для инициализации своих указателей.
Перемещение, а не копирование элементов при резервированииПрежде чем приступить к функции reallocate(), следует обдумать то, что она должна делать:
• зарезервировать память для нового, большего массива строк;
• заполнить первую часть этого пространства существующими элементами;
• удалить элементы в существующей памяти и освободить ее.
Глядя на этот список, можно заметить, что пересоздание объекта класса StrVec влечет за собой копирование каждой строки из прежнего объекта StrVec в новый. Даже без подробностей реализации класса string известно, что строки ведут себя подобно значению. После копирования новая строка и оригинальная независимы друг от друга. Изменения, внесенные в оригинал, не распространяются на копию, и наоборот.
Поскольку строки действуют, как значения, можно сделать вывод, что у каждой строки должна быть собственная копия составляющих ее символов. Копирование строки должно резервировать память для этих символов, а удаление строки должно освободить используемую ею память.
Копирование строки подразумевает копирование данных, поскольку обычно после копирования строки у нее будет два пользователя. Но когда функция reallocate() копирует строки объекта класса StrVec, у этих строк будет только один пользователь. Как только копирование элементов из прежнего пространства в новое завершается, исходные строки немедленно удаляются.
Копирование данных этих строк не нужно. Производительность класса StrVec будет значительно выше, если удастся избежать дополнительных затрат на резервирование и освобождение строк при каждом его пересоздании.
Конструктор перемещения и функция std::move()Копирования строки можно избежать при помощи двух средств, введенных новой библиотекой. Во-первых, некоторые из библиотечных классов, включая класс string, определяют так называемые конструкторы перемещения (move constructor). Подробности работы конструктора перемещения класса string (равно как и все остальные подробности его реализации) не раскрываются. Однако общеизвестно, что конструкторы перемещения обычно "перемещают" ресурсы из заданного объекта в создаваемый. Библиотека гарантирует также то, что "перемещенная" строка останется в допустимом состоянии. В случае класса string можно предположить, что у каждого его объекта есть указатель на массив типа char. По-видимому, конструктор перемещения класса string копирует указатель вместо резервирования нового пространства и копирования символов.
Второе доступное для использования средство — это библиотечная функция move(), определенная в заголовке utility. Есть два важных момента, которые следует знать о функции move(). Во-первых, по причинам, рассматриваемым в разделе 13.6.1, когда функция reallocate() создает строки в новой области памяти, она должна вызвать функцию move(), чтобы сообщить о необходимости использования конструктора перемещения класса string. Если пропустить вызов функции move(), то будет использован конструктор копий класса string. Во-вторых, по причинам, рассматриваемым в разделе 18.2.3, объявление using (см. раздел 3.1) для функции move() обычно не предоставляется. Когда используется функция move(), вызывается функция std::move(), а не move().
Функция-член reallocate()Используя эту информацию, можно написать собственную функцию reallocate(). Сначала вызовем функцию allocate(), чтобы зарезервировать новое пространство. При каждом пересоздании объекта класса StrVec будем удваивать его емкость. Если вектор StrVec пуст, резервируем место для одного элемента:
void StrVec::reallocate() {
// будем резервировать вдвое больше элементов, чем текущий размер
auto newcapacity = size() ? 2 * size() : 1;
// резервировать новую память
auto newdata = alloc.allocate(newcapacity);
// переместить данные из прежней памяти в новую
auto dest = newdata; // указывает на следующую свободную позицию в
// новом массиве
auto elem = elements; // указывает на следующий элемент в старом
// массиве
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free(); // освобождает старое пространство после перемещения
// элементов
// обновить структуру данных, чтобы указать на новые элементы
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
Цикл for перебирает существующие элементы и создает соответствующие элементы в новом пространстве. Указатель dest используется для указания на область памяти, в которой создается новая строка, а указатель elem — для указания на элемент в оригинальном массиве. Для перемещения указателей dest и elem на следующий элемент этих двух массивов используем постфиксный инкремент.
Второй аргумент в вызове функции construct() (т.е. аргумент, определяющий используемый конструктор (см. раздел 12.2.2)) является значением, возвращенным функцией move(). Вызов функции move() возвращает результат, заставляющий функцию construct() использовать конструктор перемещения класса string. Поскольку используется конструктор перемещения, управляемая память строки не будет скопирована. Вместо этого каждая создаваемая строка получит в собственность область памяти из строки, на которую указывает указатель elem.
После перемещения элементов происходит вызов функции free() для удаления прежних элементов и освобождения памяти, которую данный вектор StrVec использовал перед вызовом функции reallocate(). Сами строки больше не управляют памятью, в которой они располагались; ответственность за их данные была передана элементам нового вектора StrVec. Нам неизвестно содержимое строк в памяти прежнего вектора StrVec, но нам гарантирована безопасность запуска деструктора класса string для этих объектов.
Остается только обновить указатели адресами вновь созданного и инициализированного массива. Указатели first_free и cap обозначат элемент следующий после последнего созданного и следующий после последнего зарезервированного соответственно.
Упражнения раздела 13.5Упражнение 13.39. Напишите собственную версию класса StrVec, включая функции reserve(), capacity() (см. раздел 9.4) и resize() (см. раздел 9.3.5).
Упражнение 13.40. Добавьте в класс StrVec конструктор, получающий аргумент типа initializer_list<string>.
Упражнение 13.41. Почему в вызове функции construct() в функции push_back() был использован постфиксный инкремент? Что случилось бы при использовании префиксного инкремента?
Упражнение 13.42. Проверьте свой класс StrVec, использовав его в классах TextQuery и QueryResult (см. раздел 12.3) вместо вектора vector<string>.
Упражнение 13.43. Перепишите функцию-член free() так, чтобы для удаления элементов вместо цикла for использовалась функция for_each() и лямбда-выражение (см. раздел 10.3.2). Какую реализацию вы предпочитаете и почему?
Упражнение 13.44. Напишите класс по имени String, являющийся упрощенной версией библиотечного класса string. У вашего класса должен быть по крайней мере стандартный конструктор и конструктор, получающий указатель на строку в стиле С. Примените для резервирования используемой классом String памяти класс allocator.
13.6. Перемещение объектов
Одной из главных особенностей нового стандарта является способность перемещать объект, а не копировать. Как упоминалось в разделе 13.1.1, копирование осуществляется при многих обстоятельствах. При некоторых из них объект разрушается немедленно после копирования. В этих случаях перемещение объекта вместо копирования способно обеспечить существенное увеличение производительности.
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Язык программирования C++. Пятое издание"
Книги похожие на "Язык программирования C++. Пятое издание" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Стенли Липпман - Язык программирования C++. Пятое издание"
Отзывы читателей о книге "Язык программирования C++. Пятое издание", комментарии и мнения людей о произведении.