|
Программирование >> Инициализация объектов класса, структура
class Query { public: ... protected: Query(); ... конструктор не открытым, а защищенным: Ко второму конструктору класса Query предъявляются еще более жесткие требования: он не только должен конструировать Query в виде подобъекта производного класса, но этот производный класс должен к тому же быть NameQuery. Можно объявить конструктор закрытым, а NameQuery сделать другом класса Query. (В пред1дущем разделе mi говорили, что производный класс может получить доступ только к открытым и защищенным членам базового. Поэтому любая попытка вызвать второй конструктор из class Query { public: ... protected: Query(); ... private: explicit Query( const vector<location>& ); классов AndQuery, OrQuery или NotQuery приведет к ошибке компиляции.) (Необходимость второго конструктора спорна; вероятно, правильнее заполнить loc в функции eval() класса NameQuery. Однако принятый подход в большей степени отвечает нашей цели проиллюстрировать использование конструктора базового класса.) 17.4.2. Конструктор производного класса В классе NameQuery также определены два конструктора. Они объявлены открытыми, class NameQuery : public Query { public: explicit NameQuery( const string& ); NameQuery( const strings, const vector<location>* ); ... protected: ... поскольку ожидается, что в приложении будут создаваться объекты этого класса: виде подобъекта в составе объектов производных от него классов. Поэтому мы объявим inline NameQuery:: NameQuery( const string &name ) Query::Query() вызается неявно : name( name ) члена name. Конструктор по умолчанию базового класса Query вызывается неявно: Конструктор с двумя параметрами также принимает строку в качестве одного из них. Второй его параметр - это указатель на вектор позиций. Он передается закрытому конструктору базового класса Query. (Обратите внимание, что present нам больше не inline NameQuery:: NameQuery( const string &name, vector<location> *ploc ) : name( name ), Query( *ploc ) нужен, и мы исключили его из числа членов NameQuery.) string title( Alice ); NameQuery *pname; проверим, встречается Alice в отображении слов / / ес да, получить ассоциированн с ним вектор позиций if ( vector<location> *ploc = retrieve location( title )) pname = new NameQuery( title, ploc ); Конструкторы можно использовать так: else pname = new NameQuery( title ); В каждом из классов NotQuery, OrQuery и AndQuery определено но одному inline NotQuery:: NotQuery( Query *op = 0 ) : op( op ) {} inline OrQuery:: OrQuery( Query *lop = 0, Query *rop = 0 ) : lop( lop ), rop( rop ) inline AndQuery:: AndQuery( Query *lop = 0, Query *rop = 0 ) : lop( lop ), rop( rop ) конструктору, каждый из которых вызывает конструктор базового класса неявно: Конструктор с одним параметром принимает в качестве аргумента строку. Она передается конструктору объекта типа string, который вызывается для инициализации (В разделе 17.7 мы построим объекты каждого представления различных запросов пользователя.) из производных классов для 17.4.3. Альтернативная иерархия классов Хотя наша иерархия классов Query представляется вполне приемлемой, она вовсе не является единственно возможной. Например, AndQuery и OrQuery связаны с бинарной операцией, поэтому они в какой-то степени дублируют друг друга. Можно вынести все данные и функции-члены, общие для них, в абстрактный базовый класс BinaryQuery. Поддерево новой иерархии Query изображено на рисунке 17.2:
Рис. 17.2. Альтернативная иерархия классов Класс BinaryQuery - это тоже абстрактный базовый класс, следовательно, его фактические объекты в приложении не появляются. Разумной реализации eval() для него предложить нельзя, поэтому чисто виртуальная функция, объявленная в Query, в классе BinaryQuery останется чисто виртуальной. (Подробнее о таких функциях мы поговорим в разделе 17.5.) Две функции-члена для доступа - lop() и rop() , общие для обоих классов, переносятся выше, в BinaryQuery, и определяются как нестатические встроенные. Аналогично два члена lop и rop, объявленные в обоих классах, также переносятся в BinaryQuery и становятся нестатическими и защищенными. Открытые конструкторы обоих class BinaryQuery : public Query { public: const Query *lop() { return lop; } const Query *rop() { return rop; } protected: BinaryQuery( Query *lop, Query *rop : lop( lop ), rop( rop Query * lop; Query * rop; производных классов объединяются в один защищенн1й конструктор BinaryQuery: OrQuery
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |