В главе 17 рассматриваются имеющиеся в C++ средства поддержки объектно-ориентированного программирования и изучается влияние наследование на такие механизмы, как конструкторы, деструкторы, почленная инициализация и присваивание; для примера разрабатывается иерархия классов Query, поддерживающая систему текстового поиска, введенную в главе 6.
Темой главы 18 является изучение более сложных иерархий, возможных за счет использования множественного и виртуального наследования. С его помощью мы развернем шаблон класса из главы 16 в трехуровневую иерархию.
В главе 19 обсуждается идентификация типов во время выполнения (RTTI), а также изучается вопрос о влиянии наследования на разрешение перегруженных функций. Здесь мы снова обратимся к средствам обработки исключений, чтобы разобраться в иерархии классов исключений, которую предлагает стандартная библиотека. Мы покажем также, как написать собственные такие классы.
Глава 20 посвящена углубленному рассмотрению библиотеки потокового ввода/вывода iostream. Эта библиотека представляет собой иерархию классов, поддерживающую как виртуальное, так и множественное наследование.
17. Наследование и подтипизация классов
В главе 6 для иллюстрации обсуждения абстрактных контейнерных типов мы частично реализовали систему текстового поиска и инкапсулировали ее в класс TextQuery. Однако мы не написали к ней никакой вызывающей программы, отложив реализацию поддержки формулирования запросов со стороны пользователя до рассмотрения объектно-ориентированного программирования. В этой главе язык запросов будет реализован в виде иерархии классов Query с одиночным наследованием. Кроме того, мы модифицируем и расширим класс TextQuery из главы 6 для получения полностью интегрированной системы текстового поиска.
Программа для запуска нашей системы текстового поиска будет выглядеть следующим образом:
#include "TextQuery.h"
int main()
{
TextQuery tq;
tq.build_up_text();
tq.query_text();
}
build_text_map() - это слегка видоизмененная функция-член doit() из главы 6. Ее основная задача - построить отображение для хранения позиций всех значимых слов текста. (Если помните, мы не храним семантически нейтральные слова типа союзов if, and, but и т.д. Кроме того, мы заменяем заглавные буквы на строчные и устраняем суффиксы, обозначающие множественное число: например, testifies преобразуется в testify, а marches в march.) С каждым словом ассоциируется вектор позиций, в котором хранятся номера строки и колонки каждого вхождения слова в текст.
query_text() принимает запросы пользователя и преобразует их во внутреннюю форму на основе иерархии классов Query с одиночным наследованием и динамическим связыванием. Внутреннее представление запроса применяется к отображению слов на вектор позиций, построенному в build_text_map(). Ответом на запрос будет множество строк текстового файла, удовлетворяющих заданному критерию:
Enter a query - please separate each item by a space.
Terminate query (or session) with a dot( . ).
== fiery && ( bird || shyly )
fiery ( 1 ) lines match
bird ( 1 ) lines match
shyly ( 1 ) lines match
( bird || shyly ) ( 2 ) lines match
fiery && ( bird || shyly ) ( 1 ) lines match
Requested query: fiery && ( bird || shyly )
( 3 ) like a fiery bird in flight. A beautiful fiery bird, he tells her.
В нашей системе мы выбрали следующий язык запросов:
1. одиночное слово, например Alice или untamed. Выводятся все строки, в которых оно встречается, причем каждой строке предшествует ее номер, заключенный в скобки. (Строки печатаются в порядке возрастания номеров). Например:
== daddy
daddy ( 3 ) lines match
Requested query: daddy
( 1 ) Alice Emma has long flowing red hair. Her Daddy says
( 4 ) magical but untamed. "Daddy, shush, there is no such thing,"
( 6 ) Shyly, she asks, "I mean, Daddy, is there?"
1. запрос "НЕ", формулируемый с помощью оператора !. Выводятся все строки, где не встречается указанное слово. Например, так формулируется отрицание запроса 1:
== ! daddy
daddy ( 3 ) lines match
! daddy ( 3 ) lines match
Requested query: ! daddy
( 2 ) when the wind blows through her hair, it looks almost alive,
( 3 ) like a fiery bird in flight. A beautiful fiery bird, he tells her,
( 5 ) she tells him, at the same time wanting him to tell her more.
запрос "ИЛИ", формулируемый с помощью оператора ||. Выводятся все строки, в которых встречается хотя бы одно из двух указанных слов:
== fiery || untamed