|
Программирование >> Инициализация объектов класса, структура
#include Query.h main() NameQuery nm( alice ); NameQuery nm( emma ); NotQuery nq1( &nm ); cout << notQuery 1: << nq1 << endl; NotQuery nq2( nq1 ); cout << notQuery 2: << nq2 << endl; NotQuery nq3( &nm2 ); cout << notQuery 3: << nq3 << endl; nq3 = nq2; cout << notQuery 3 присвоено значение nq2: << nq3 << endl; AndQuery aq( &nq1, &Tm2 ); cout << AndQuery : << aq << endl; AndQuery aq2( aq ); cout << AndQuery 2: << aq2 << endl; AndQuery aq3( &nm, &nm2 ); cout << AndQuery 3: << aq3 << endl; aq2 = aq3; cout << AndQuery 2 после присваивания: << aq2 << endl; создаем или копируем объект, а затем распечатываем его. После компиляции и запуска программа печатает следующее: notQuery 1: ! alice notQuery 2: ! alice notQuery 3: ! notQuery 3 прис AndQuery : ! alice AndQuery 2: ! alice AndQuery 3: alice & AndQuery 2 после присваивания: alice && emma emma 3 присвоено значение nq2: ! alice lice && emma Упражнение 17.18 Реализуйте копирующие конструкторы в классах AndQuery и OrQuery. Упражнение 17.19 Реализуйте копирующие операторы присваивания в классах AndQuery и OrQuery. Упражнение 17.20 (*static cast<Query*>(this)) = rhs; (Реализация копирующих операторов присваивания в классах AndQuery и OrQuery выглядит так же, поэтому мы оставим ее в качестве упражнения.) Ниже предложена небольшая программа для тестирования данной реализации. М1 AndQuery NameQuery( fiery ) OrQuery NameQuery( bird ) то в нашу задачу входит построение эквивалентной иерархии классов: NameQuery( potato ) Как лучше всего это сделать? Процедура вычисления ответа на запрос напоминает функционирование конечного автомата. Mi начинаем с пустого состояния и при обработке каждого элемента запроса переходим в новое состояние, пока весь запрос не будет разобран. В основе нашей реализации лежит одна инструкция switch внутри операции, которую мы назвали eval query() . Слова запроса считываются одно за другим из вектора строк и сравниваются с каждым из возможных значений: Что указывает на необходимость реализации явных копирующего конструктора и копирующего оператора присваивания? 17.7. Управляющий класс UserQuery Если имеется запрос такого тина: [ fiery && ( bird potato ) vector<string>::iterator query->begin(), end it = query->end(); for ( ; it != end it; ++it ) switch( evalQueryStri tring( *it )) case WORD: evalWord( *it ); break; case AND: evalAnd(); break; case OR: evalOr(); break; case NOT: evalNot(); break; case LPAREN: ++ paren; ++ lparenOn; break; case RPAREN: -- paren; ++ rparenOn; evalRParen(); break; Пять операций eval: evalWord() , evalAnd() , evalOr() , evalNot и evalRParen() - как раз и строят иерархию классов Query. Прежде чем обратиться к деталям их реализации, рассмотрим общую организацию программы. Нам нужно определить каждую операцию в виде отдельной функции, как это было сделано в главе 6 при построении процедур обработки запроса. Пользовательский запрос и производные от Query классы представляют независимые данные, которыми оперируют эти функции. От такой модели программирования (она называется процедурной) мы предпочли отказаться. В разделе 6.14 мы ввели класс TextQuery, где инкапсулировали операции и данные, изучавшиеся в главе 6. Здесь нам потребуется класс UserQuery, решающий аналогичн1е задачи. Одним из членов этого класса должен быть вектор строк, содержащий сам запрос пользователя. Другой член - это указатель типа Query* на иерархическое представление запроса, построенное в eval query(). Еще три члена служат для обработки скобок: paren помогает изменить подразумеваем1й порядок вычисления операторов (чуть позже мы продемонстрируем это на примере); lparenOn и rparenOn содержат счетчики левых и правых скобок, ассоциированные с текущим узлом дерева разбора запроса (мы показывали, как они используются, при обсуждении виртуальной функции print() в разделе 17.5.1).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |