Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
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.39. Напишите собственную версию класса StrVec, включая функции reserve(), capacity()(см. раздел 9.4) и resize()(см. раздел 9.3.5).
Упражнение 13.40. Добавьте в класс StrVecконструктор, получающий аргумент типа initializer_list.
Упражнение 13.41. Почему в вызове функции construct()в функции push_back()был использован постфиксный инкремент? Что случилось бы при использовании префиксного инкремента?
Упражнение 13.42. Проверьте свой класс StrVec, использовав его в классах TextQueryи QueryResult(см. раздел 12.3) вместо вектора vector.
Упражнение 13.43. Перепишите функцию-член free()так, чтобы для удаления элементов вместо цикла forиспользовалась функция for_each()и лямбда-выражение (см. раздел 10.3.2). Какую реализацию вы предпочитаете и почему?
Упражнение 13.44. Напишите класс по имени String, являющийся упрощенной версией библиотечного класса string. У вашего класса должен быть по крайней мере стандартный конструктор и конструктор, получающий указатель на строку в стиле С. Примените для резервирования используемой классом Stringпамяти класс allocator.
13.6. Перемещение объектов
Одной из главных особенностей нового стандарта является способность перемещать объект, а не копировать. Как упоминалось в разделе 13.1.1, копирование осуществляется при многих обстоятельствах. При некоторых из них объект разрушается немедленно после копирования. В этих случаях перемещение объекта вместо копирования способно обеспечить существенное увеличение производительности.
Как было продемонстрировано только что, наш класс StrVec— хороший пример лишнего копирования. Во время пересоздания нет никакой необходимости в копировании элементов из старой памяти в новую, лучше перемещение. Вторая причина предпочесть перемещение копированию — это такие классы как unique_ptrи классы ввода-вывода. У этих классов есть ресурс (такой как указатель или буфер ввода-вывода), который не допускает совместного использования. Следовательно, объекты этих типов не могут быть скопированы, но могут быть перемещены.
В прежних версиях языка не было непосредственного способа перемещения объекта. Копию приходилось делать, даже если в этом не было никакой потребности. Когда объекты велики или когда они требуют резервирования памяти (например, строки), бесполезное копирование может обойтись очень дорого. Точно так же в предыдущих версиях библиотеки классы хранимых в контейнере объектов должны были допускать копирование. По новому стандарту в контейнерах можно хранить объекты типов, которые не допускают копирования, но могут быть перемещены.
Контейнеры библиотечных типов, классы stringи shared_ptrподдерживают как перемещение, так и копирование. Классы ввода-вывода и класс unique_ptrдопускают перемещение, но не копирование.
13.6.1. Ссылки на r-значение
Для обеспечения операции пересылки, новый стандарт вводит новый вид ссылок — ссылки на r-значение. Ссылка на r-значение (r-value reference) — это ссылка, которая должна быть связана с r-значением. Ссылку на r-значение получают с использованием символа &&, а не &. Как будет продемонстрировано далее, у ссылок на r-значение есть важное свойство — они могут быть связаны только с тем объектом, который будет удален. В результате можно "перемещать" ресурсы от ссылки на r-значение в другой объект.
Интервал:
Закладка: