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

1 ... 302 303 304 [ 305 ] 306 307 308 ... 395


опредеть объект, не имея запроса пользователя

UserQuery user query; string text;

vector<string> ery text; обработать запросы пользователя

do {

while( cin >> text )

query text.push back( text );

передать запрос объекту UserQuery user ery.query( &query text );

вгчисть результат запроса и вернуть корень иерархии Query* Query *query = user query.eval query();

while ( /* пользователь продоает формулировать запросы */ ); Вот определение нашего класса UserQuery:



#ifndef USER QUERY H #define USER QUERY H

#include <string> #include <vector> #include <map> #include <stack>

typedef pair<short,short> location;

typedef vector<location,allocator> loc;

#include Query.h

class UserQuery { public:

UserQuery( vector< string,allocator > *pery = 0 ) : ery( pery ), eval( 0 ), paren( 0 ) {}

Query *eval query(); строит иерархию

void query( vector< string,allocator > *pq ); void displayQuery();

static void word map( map<string,loc*,less<string>,allocator> *pwm ) {

if ( ! word map ) word map = pwm;

private:

enum eryType { WORD = 1, AND, OR, NOT, RPAREN, LPAREN };

QueryType evalQueryString( const string &query ); void evalWord( const string Sery );

void evalAnd();

void evalOr();

void evalNot();

void evalRParen();

bool integrity check();

int paren;

Query * eval;

vector<string> * query;

stack<Query*, vector<Query*> > query stack; stack<Query*, vector<Query*> > current op; static short lparenOn, rparenOn;

static map<string,loc*,less<string>,allocator> * word map;

#endif

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

Ниже показаны реализации различных встроенных операций eval. Операции evalAnd() и evalOr() выполняют следующие шаги. Сначала объект извлекается из стека



inline void UserQuery::

evalAnd()

Query *pop = query stack.top(); query stack.pop();

AndQuery *pq = new AndQuery( pop );

if ( lparenOn ) { pq->lparen( lparenOn ); lparenOn = 0; }

if ( rparenOn ) { pq->rparen( rparenOn ); rparenOn = 0; }

current op.push( pq );

inline void UserQuery::

evalOr()

Query *pop = ery stack.top(); ery stack.pop();

OrQuery *pq = new OrQuery( pop );

if ( lparenOn ) { pq->lparen( lparenOn ); lparenOn = 0; }

if ( rparenOn ) { pq->rparen( rparenOn ); rparenOn = 0; }

current op.push( pq );

помещается в стек current op:

Операция evalNot() работает следующим образом. В хипе создается новый объект класса NotQuery, которому передаются счетчики левых и правых скобок для правильного

inline void UserQuery::

evalNot()

NotQuery *pq = new NotQuery;

if ( lparenOn ) { pq->lparen( lparenOn ); lparenOn = 0; }

if ( rparenOn ) { pq->rparen( rparenOn ); rparenOn = 0; }

current op.push( pq );

отображения содержимого. Затем неполный оператор помещается в стек current op:

query stack (напомним, что для класса stack, определенного в стандартной библиотеке, это требует двух операций: top() для получения элемента и pop() для удаления его из стека). Затем из хипа выделяется память для объекта класса AndQuery или OrQuery, и указатель на него передается объекту, извлеченному из стека. Каждая операция передает объекту AndQuery или OrQuery счетчики левых или правых скобок, необходим1е ему для вывода своего содержимого. И наконец неполный оператор



1 ... 302 303 304 [ 305 ] 306 307 308 ... 395

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