Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Класс
BinaryQuery
не переопределяет функцию eval()
, а следовательно, наследует ее чистой виртуальной. Таким образом, класс BinaryQuery
остается абстрактным и его объекты создавать нельзя.
AndQuery
, OrQuery
и их операторыКлассы AndQuery
и OrQuery
, а также соответствующие им операторы очень похожи:
class AndQuery: public BinaryQuery {
friend Query operators(const Query&, const Query&);
AndQuery(const Query &left, const Query &right):
BinaryQuery(left, right, "&") { }
// конкретный класс: AndQuery наследует функцию rep(),
// а остальные чистые виртуальные функции переопределяет
QueryResult eval(const TextQuery&) const;
};
inline Query operator&(const Query &lhs, const Query &rhs) {
return std::shared_ptr(new AndQuery(lhs, rhs));
}
class OrQuery: public BinaryQuery {
friend Query operator|(const Query&, const Query&);
OrQuery(const Query &left, const Query &right):
BinaryQuery(left, right, "|") { }
QueryResult eval(const TextQuery&) const;
};
inline Query operator|(const Query &lhs, const Query &rhs) {
return std::shared_ptr(new OrQuery(lhs, rhs));
}
Эти классы объявляют соответствующий оператор дружественным и определяют конструктор, создающий их базовую часть класса BinaryQuery
с соответствующим оператором. Они наследуют определение функции rep()
от класса BinaryQuery
, но каждый из них определяет собственную версию функции eval()
.
Как и оператор операторы & и |
возвращают указатель shared_ptr
на вновь созданный объект соответствующего типа. Этот указатель shared_ptr
приводится к типу Query
в операторе return
каждого из этих операторов.
Упражнение 15.34. Исходя из выражения, представленного на рис. 15.3:
(a) Перечислите конструкторы, задействованные при обработке этого выражения;
(b) Перечислите обращения к функции rep()
из выражения cout << q
;
(c) Перечислите обращения к функции eval()
из выражения q.eval
.
Упражнение 15.35. Реализуйте классы Query
и Query_base
, включая определение функции rep()
, но исключая определение функции eval()
.
Упражнение 15.36. Добавьте операторы вывода в конструкторы и функции-члены rep()
. Запустите код на выполнение, чтобы проверить свои ответы на вопросы (а) и (b) первого упражнения.
Упражнение 15.37. Какие изменения следовало бы внести в классы, если бы у производных классов были члены типа shared_ptr
, а не типа Query
?
Упражнение 15.38. Допустимы ли следующие объявления? Если нет, то почему? Если да, то что они означают?
BinaryQuery а = Query("fiery") & Query("bird");
AndQuery b = Query("fiery") & Query("bird");
OrQuery с = Query("fiery") & Query("bird");
15.9.4. Виртуальные функции eval()
Функции eval()
— основа системы запросов. Каждая из них вызывает функцию eval()
своего операнда (операндов), а затем применяет собственную логику вычислений: функция eval()
класса OrQuery
возвращает объединение результатов своих операндов, а функция eval()
класса AndQuery
возвращает их пересечение. Функция eval()
класса NotQuery
немного сложней: она должна возвращать номера строк, не входящих в набор операнда.
Для обеспечения обработки в функциях eval()
необходимо использовать ту версию класса QueryResult
, в который определены члены, добавленные в упражнениях раздела 12.3.2. Подразумевается, что у класса QueryResult
есть функции-члены begin()
и end()
, позволяющие перебрать набор номеров строк, которые содержит объект класса QueryResult
. Подразумевается также, что у класса QueryResult
есть функция-член get_file()
, возвращающая указатель shared_ptr
на файл, к которому осуществляется запрос.
Класс
Query
использует функции-члены begin()
и end()
, определенные для класса QueryResult
в упражнении 12.3.2.
OrQuery::eval()
Функция eval()
класса OrQuery
объединяет наборы номеров строк, возвращенных его операндами, т.е. ее результатом является объединение результатов двух операндов.
Объект класса OrQuery
представляет объединение результатов двух своих операндов, полученных при вызове функции-члена eval()
каждого из них. Поскольку эти операнды являются объектами класса Query
, вызов функции eval()
является вызовом Query::eval()
, который в свою очередь осуществляет виртуальный вызов функции eval()
объекта базового класса Query_base
. Каждый из этих вызовов возвращает объект класса QueryResult
, представляющий номера строк, в которых присутствует его операнд. Эти номера строк объединяются в новый набор:
// возвращает объединение наборов результатов своих операндов
QueryResult
OrQuery::eval(const TextQuery& text) const {
// виртуальные вызовы через члены Query, lhs и rhs
// вызовы eval() возвращают QueryResult для каждого операнда
auto right = rhs.eval(text), left = lhs.eval(text);
// копировать номера строк левого операнда в результирующий набор
auto ret_lines =
make_shared>(left.begin(), left.end());
// вставить строки из правого операнда
ret_lines->insert(right.begin(), right.end());
// возвратить новый QueryResult, представляющий объединение lhs и rhs
return QueryResult(rep(), ret_lines, left.get_file());
}
Набор ret_lines
инициализируется с использования того конструктора, который получает пару итераторов. Функции-члены begin()
и end()
класса QueryResult
возвращают итераторы на номера строк набора. Таким образом, набор ret_lines
создается при копировании элементов из набора left
. Затем для вставки элементов из набора right
вызывается функция insert()
. После этого вызова набор ret_lines
содержит номера строк из наборов, которые присутствуют в наборах left
или right
.
Функция eval()
завершает работу, создавая и возвращая объект класса QueryResult
, представляющий объединение соответствий. Конструктор QueryResult()
(см. раздел 12.3.2) получает три аргумента: строку, представляющую запрос, указатель shared_ptr
на набор соответствующих номеров строк и указатель shared_ptr
на вектор, представляющий входной файл. Вызов функции rep()
позволяет создать строку, а вызов функции get_file()
— получить указатель shared_ptr
на файл. Поскольку оба набора, left
и right
, относятся к тому же файлу, не имеет значения, который из них использовать для функции get_file()
.
AndQuery::eval()
Версия функции eval()
класса AndQuery
подобна версии класса OrQuery
, за исключением того, что она использует библиотечный алгоритм для поиска строк, общих для обоих запросов:
Интервал:
Закладка: