Программирование >>  Инициализация объектов класса, структура 

1 ... 283 284 285 [ 286 ] 287 288 289 ... 395


typedef vector<location> loc; class NameQuery : public Query {

public:

переопределяет виртуальна функцию Query::eval( )2 virtual void eval();

функция чтения

string name() const { return name; }

static const map<string,loc*> *word map() { return word map; } protected:

string name; static map<string,loc*> * word map;

присваивания мы снова отложим) выглядит так: };

Класс NotQuery в дополнение к предоставлению реализации виртуальной функции eval() должен обеспечить поддержку своего единственного операнда. Поскольку им может быть объект любого из производных классов, определим его как указатель на тип Query. Результат запроса NotQuery, напомним, обязан содержать не только строки текста, где нет указанного слова, но также и номера колонок внутри каждой строки. Например, если есть запрос:

Pi daddy

то операнд запроса NotQuery включает следующий вектор позиций:

[ daddy ((0,8), (3,3),(5,5) )

Вектор позиций, возвращаемый в ответ на исходный запрос, должен включать все номера колонок в строках (1,2,4). Кроме того, он должен включать все номера колонок в строке (0), кроме колонки (8), все номера колонок в строке (3), кроме колонки (3), и все номера колонок в строке (5), кроме колонки (5).

2 В объявлении унаследованной виртуальной функции, например eval(), в производном классе ключевое слово virtual необязательно. Компилятор делает правильное заключение на основе сравнения с прототипом функции.

Кроме того, нужна поддержка для хранения слова-операнда, представленного объектом класса типа string.

Наконец, для получения ассоциированного вектора позиций должно быть доступно отображение слов на векторы. Поскольку один такой объект разделяется всеми объектами класса NameQuery, мы объявляем его статическим членом. Первая попытка определения NameQuery (рассмотрение конструкторов, деструктора и копирующего оператора



class NotQuery : public Query { public:

альтернативный синтаксис: явно употреблено ключевое слово virtual переопределение Query::eval() virtual void eval();

функция доступа для чтения

const Query *op() const { return op; } static const vector< location > * all locs()

return all locs;

protected:

Query * op; static const

vector< location > * all locs;

копирующего оператора присваивания отложено): };

Классы AndQuery и OrQuery представляют бинарные операции, у которых есть левый и правый операнды. Оба операнда могут быть объектами любого из производных классов, поэтому мы определим соответствующие члены как указатели на тип Query. Кроме того, в каждом классе нужно переопределить виртуальную функцию eval() . Вот начальное

class OrQuery : public Query {

public:

...

virtual void eval();

const Query *rop() const { return rop; } const Query *lop() const { return lop; }

protected:

Query * lop; Query * rop;

определение OrQuery: };

Любой объект AndQuery должен иметь доступ к числу слов в каждой строке. В противном случае при обработке запроса AndQuery мы не сможем найти соседние слова, расположенные в двух смежных строках. Например, если есть запрос:

i tell && her && magical

Простейший способ вычислить все это - создать единственный разделяемый всеми объектами вектор позиций, который содержит пары (строка, колонка) для каждого слова в тексте (полную реализацию мы рассмотрим в разделе 17.5, когда будем обсуждать функцию eval() класса NotQuery). Так или иначе, этот член мы объявим статическим для NotQuery.

Вот определение класса NotQuery (и снова рассмотрение конструкторов, деструктора и



like a fiery bird in flight. A beautiful fiery bird, he tells her, magical but untamed. Daddy, shush, there is no such thing,

Векторы позиций, ассоциированные с каждым из трех слов, следующие:

her ((0,7),(1,5),(2,12),(4,11))

magical ((3,0))

tell ((2,11),(4,1),(4,10))

Если функция eval() класса AndQuery не знает , сколько слов содержится в строке (2), то она не сможет определить, что слова magical и her соседствуют. Мы создадим единственный экземпляр вектора, разделяемый всеми объектами класса, и объявим его статическим членом. (Реализацию eval() м1 детально рассмотрим в разделе 17.5.) Итак,

class AndQuery : public Query { public:

public:

конструкторы обсуждаются в разделе 17.4 virtual void eval();

const Query *rop() const { return rop; } const Query *lop() const { return lop; }

static void max col( const vector< int > *pcol ) { if ( l max col ) max col = pcol; }

protected:

Query * lop; Query * rop;

static const vector< int > * max col; определим AndQuery:

17.2.3. Резюме

Открытый интерфейс каждого из четырех производных классов состоит из их открытых членов и унаследованных открытых членов Query. Когда мы пишем:

Query *pq = new NmaeQuery( Monet );

то получить доступ к открытому интерфейсу Query можно только через pq. А если пишем:

pq->eval();

то вызывается реализация виртуальной eval() из производного класса, на объект которого указывает pq, в данном случае - из класса NameQuery. Строкой

pq->display();

то нужная последовательность находится в третьей и четвертой строках:



1 ... 283 284 285 [ 286 ] 287 288 289 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.236
При копировании материалов приветствуются ссылки.
Яндекс.Метрика