Поисковую систему можно было бы усовершенствовать, добавив еще одну разновидность запроса “И”, которую мы назовем InclusiveAndQuery и будем обозначать символом &. Строка текста удовлетворяет условиям запроса, если в ней находятся оба указанных слова, пусть даже не рядом. Например, строка
We were her pride of ten, she named us
удовлетворяет запросу:
pride & ten
но не:
pride && ten
Поддержите запрос InclusiveAndQuery.
Упражнение 17.25
Представленная ниже реализация функции display_solution() может выводить только в стандартный вывод. Более правильно было бы позволить пользователю самому задавать поток ostream, в который надо направить вывод. Модифицируйте display_solution() так, чтобы ostream можно было задавать. Какие еще изменения необходимо внести в определение класса UserQuery?
void TextQuery::
display_solution()
{
cout "\n"
"Requested query: "
*query "\n\n";
const setshort,lessshort,allocator *solution = query-solution();
if ( ! solution-size() ) {
cout "\n\t"
"Sorry, no matching lines were found in text.\n"
endl;
}
setshort::const_iterator
it = solution-begin(),
end_it = solution-end();
for ( ; it != end_it; ++it ) {
int line = *it;
// пронумеруем строки с 1 ...
cout "( " line+1 " ) "
(*lines_of_text)[line] '\n';
}
cout endl;
}
Упражнение 17.26
Нашему классу TextQuery не хватает возможности принимать аргументы, заданные пользователем в командной строке.
Предложите синтаксис командной строки для нашей поисковой системы.
Добавьте в класс необходимые данные и функции-члены.
Предложите средства для работы с командной строкой (см. пример в разделе 7.8).
Упражнение 17.27
В качестве темы для рабочего проекта рассмотрите следующие усовершенствования нашей поисковой системы:
Реализуйте поддержку, необходимую для представления запроса AndQuery в виде одной строки, например "Motion Picture Screen Cartoonists".
Реализуйте поддержку для ответа на запрос на основе вхождения слов не в строку, а в предложение.
Реализуйте подсистему хранения истории, с помощью которой пользователь мог бы ссылаться на предыдущий запрос по номеру, возможно, комбинируя его с новым запросом.
Вместо того чтобы показывать счетчик найденных и все найденные строки, реализуйте возможность задать диапазон выводимых строк для промежуточных вычислений и для окончательного ответа:
== John && Jacob && Astor
(1) john ( 3 ) lines match
(2) jacob ( 3 ) lines match
(3) john && jacob ( 3 ) lines match
(4) astor ( 3 ) lines match
(5) john && jacob && astor ( 5 ) lines match
// Новая возможность: пусть пользователь укажет, какой запрос выводить
// пользователь вводит число
== вывести? 3
// Затем система спрашивает, сколько строк выводить
// при нажатии клавиши Enter выводятся все строки,
// но пользователь может также ввести номер одной строки или диапазон
сколько (Enter выводит все, иначе введите номер строки или диапазон) 1-3
18. Множественное и виртуальное наследование
В большинстве реальных приложений на C++ используется открытое наследование от одного базового класса. Можно предположить, что и в наших программах оно в основном будет применяться именно так. Но иногда одиночного наследования не хватает, потому что с его помощью либо нельзя адекватно смоделировать абстракцию предметной области, либо получающаяся модель чересчур сложна и неинтуитивна. В таких случаях следует предпочесть множественное наследование или его частный случай – виртуальное наследование. Их поддержка, имеющаяся в C++, – основная тема настоящей главы.
18.1. Готовим сцену
Прежде чем детально описывать множественное и виртуальное наследование, покажем, зачем оно нужно. Наш первый пример взят из области трехмерной компьютерной графики. Но сначала познакомимся с предметной областью.