Как и оператор операторы & и |
возвращают указатель 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 {
//
//
auto right = rhs.eval(text), left = lhs.eval(text);
//
auto ret_lines =
make_shared
//
ret_lines->insert(right.begin(), right.end());
//
return QueryResult(rep(), ret_lines, left.get_file());
}