|
Программирование >> Инициализация объектов класса, структура
опредеть объект, не имея запроса пользователя 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е ему для вывода своего содержимого. И наконец неполный оператор
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |