Вот определение класса NotQuery (и снова рассмотрение конструкторов, деструктора и копирующего оператора присваивания отложено):
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(). Вот начальное определение OrQuery:
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;
};
Любой объект AndQuery должен иметь доступ к числу слов в каждой строке. В противном случае при обработке запроса AndQuery мы не сможем найти соседние слова, расположенные в двух смежных строках. Например, если есть запрос:
tell && her && magical
то нужная последовательность находится в третьей и четвертой строках:
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() мы детально рассмотрим в разделе 17.5.) Итак, определим AndQuery:
class AndQuery : public Query {
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 ( !_max_col ) _max_col = pcol; }
protected:
Query *_lop;
Query *_rop;
static const vector< int > *_max_col;
};