Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Executing Query for: ((fiery & bird) | wind)
((fiery & bird) | wind) occurs 3 times
(line 2) Her Daddy says when the wind blows
(line 4) like a fiery bird in flight.
(line 5) A beautiful fiery bird, he tells her,
В отображаемом результате для указания способа интерпретации запроса используются круглые скобки. Подобно первоначальной реализации, система не должна отображать одинаковые строки несколько раз.
15.9.1. Объектно-ориентированное решение
Для представления запросов на поиск слов вполне логично было бы использовать класс TextQuery
(см. раздел 12.3.2), а другие классы запросов можно было бы получить как производные от этого класса.
Однако такой подход неверен. Концептуально инверсный запрос не является разновидностью запроса на поиск слова. Инверсный запрос — это скорее запрос типа "имеет" (запрос на поиск слова или любой другой тип запроса), результат которого интерпретируется негативно.
Исходя из этого можно сделать вывод, что разные виды запросов следует оформить как независимые классы, которые совместно используют общий базовый класс:
WordQuery // Daddy
NotQuery // ~Alice
OrQuery // hair | Alice
AndQuery // hair & Alice
Эти классы будет иметь только две функции.
• Функция eval()
, получающая объект класса TextQuery
и возвращающая объект класса QueryResult
. Для поиска запрошенной строки функция eval()
будет использовать переданный объект класса TextQuery
.
• Функция rep()
, возвращающая строковое представление базового запроса. Эту функцию использует функция eval()
для создания объекта класса QueryResult
, представляющего соответствия, а также оператор вывода, отображающий выражение запроса.
Как уже упоминалось, все четыре типа запроса не связаны друг с другом наследованием; концептуально они элементы одного уровня. Каждый класс использует тот же интерфейс, а значит, для представления этого интерфейса следует определить абстрактный базовый класс (см. раздел 15.4). Назовем этот абстрактный базовый класс Query_base
, поскольку он должен служить корневым классом иерархии запроса.
Проектирование иерархии наследования — это достаточно сложная тема, которая выходит за рамки данного вводного курса. Однако имеет смысл упомянуть об одном достаточно важном факторе проектирования, с которым должен быть знаком каждый программист.
При определении класса как открыто производного от другого производный и базовый классы реализуют взаимоотношения типа " является " (is а). В хорошо проработанных иерархиях объекты открыто унаследованных классов применимы везде, где ожидается объект базового класса.
Еще одним популярным способом взаимоотношений классов является принцип " имеет " (has а). Типы, связанные отношениями " имеет ", подразумевают принадлежность.
В рассматриваемом примере с книжным магазином базовый класс представляет концепцию книги, продаваемой по предусмотренной цене, а класс Bulk_quote
" является " конкретной книгой, продаваемой по розничной цене с определенной стратегией скидок. Классы приложения книжного магазина " имеют " цену и ISBN.
Класс Query_base
определит функции eval()
и rep()
как чистые виртуальные (см. раздел 15.4). Каждый из классов, представляющих специфический вид запроса, должен переопределить эти функции. Классы WordQuery
и NotQuery
унаследуем непосредственно от класса Query_base
. У классов AndQuery
и OrQuery
будет одна общая особенность, которой не будет у остальных классов в системе: у каждого будет по два операнда. Для моделирования этой особенности определим другой абстрактный базовый класс, BinaryQuery
, представляющий запросы с двумя операндами. Классы AndQuery
и OrQuery
наследуются от класса BinaryQuery
, который в свою очередь наследуется от класса Query_base
. Результатом этих решений будет проект классов, представленный на рис. 15.2.

Рис. 15.2. Иерархия наследования Query_base
Рассматриваемая программа будет отрабатывать запросы, а не создавать их. Но чтобы запустить программу на выполнение, необходимо определить способ создания запроса. Проще всего сделать это непосредственно в коде при помощи выражения С++. Например, чтобы создать описанный ранее составной запрос, можно использовать следующий код:
Query q = Query("fiery") & Query("bird") | Query ("wind");
Это довольно сложное описание неявно предполагает, что код пользовательского уровня не будет использовать унаследованные классы непосредственно. Вместо этого будет создан класс интерфейса по имени Query
(Запрос), который и скроет иерархию. Класс Query
будет хранить указатель на класс Query_base
. Этот указатель будет связан с объектом типа, производного от класса Query_base
. Класс Query
будет предоставлять те же функции, что и классы Query_base
: функцию eval()
для обработки соответствующего запроса и функцию rep()
для создания строковой версии запроса. В нем также будет определен перегруженный оператор вывода, чтобы отображать соответствующий запрос.
Пользователи будут создавать объекты класса Query_base
и работать с ними только косвенно, через функции объектов класса Query
. Для класса Query
, наряду с получающим строку конструктором, определим три перегруженных оператора. Каждая из этих функций будет динамически резервировать новый объект типа, производного от класса Query_base
:
• Оператор &
создает объект класса Query
, связанный с новым объектом класса AndQuery
.
• Оператор |
создает объект класса Query
, связанный с новым объектом класса OrQuery
.
• Оператор ~
создает объект класса Query
, связанный с новым объектом класса NotQuery
.
• Конструктор класса Query
, получающий строку и создающий новый объект класса WordQuery
.
Следует понять, что работа этого приложения состоит в основном из построения объектов для представления запросов пользователя. Например, приведенное выше выражение создает коллекцию взаимодействовавших объектов, представленных на рис. 15.3.

Рис. 15.3. Объекты, созданные выражениями запросов
Как только создано дерево объектов, обработка (или отображение) данного запроса сводится к простому процессу (осуществляемому компилятором), который, следуя по линиям, опрашивает каждый объект дерева, чтобы выполнить (или отобразить) необходимые действия. Например, если происходит вызов функции eval()
объекта q
(т.е. корневого класса дерева), функция eval()
опросит объект класса OrQuery
, на который он указывает. Обработка этого объекта класса OrQuery
приведет к вызову функции eval()
для двух его операндов, что, в свою очередь, приведет к вызову функции eval()
для объектов классов AndQuery
и WordQuery
, которые осуществляют поиск слова wind
. Обработка объекта класса AndQuery
, в свою очередь, приведет к обработке двух его объектов класса WordQuery
, создав результаты для слов fiery
и bird
соответственно.
Интервал:
Закладка: