Читаем Язык программирования C++. Пятое издание полностью

Обе функции, eval() и rep(), являются чистыми виртуальными, что делает класс Query_base абстрактным базовым (см. раздел 15.4). Поскольку класс Query_base не предназначен для пользователей и непосредственного использования в производных классах, у него нет открытых членов. Класс Query_base будет использоваться только через объекты класса Query. Класс предоставляет дружественные отношения классу Query, поскольку его члены вызывают виртуальные функции класса Query_base.

Защищенный член line_no будет использоваться в функциях eval(). Деструктор также будет защищен, поскольку он используется (неявно) деструкторами в производных классах.

Класс Query

Класс Query предоставляет интерфейс к иерархии наследования Query_base и скрывает ее. Каждый объект класса Query содержит указатель shared_ptr на соответствующий объект класса Query_base. Поскольку класс Query — единственный интерфейс к классам иерархии Query_base, он должен определить собственные версии функций eval() и rep().

Конструктор Query(), получающий строку, создаст новый объект класса WordQuery и свяжет его указатель-член shared_ptr с этим недавно созданным объектом. Операторы &, | и ~ создают объекты AndQuery, OrQuery и NotQuery соответственно. Эти операторы возвращают объект класса Query, связанный с созданным им объектом. Для поддержки этих операторов класс Query нуждается в конструкторе, получающем указатель shared_ptr на класс Query_base и сохраняющем его. Сделаем этот конструктор закрытым, поскольку объекты класса Query_base не предназначены для определения общим пользовательским кодом. Так как этот конструктор является закрытым, операторы следует сделать дружественными.

Исходя из приведенного выше проекта, сам класс Query довольно прост:

// класс интерфейса для взаимодействия с иерархией

// наследования Query_base

class Query {

 // эти операторы должны обращаться к указателю shared_ptr

 friend Query operator~(const Query &);

 friend Query operator|(const Query&, const Query&);

 friend Query operator&(const Query&, const Query&);

public:

 Query(const std::string&); // создает новый WordQuery

 // функции интерфейса: вызывают соответствующий оператор Query_base

 QueryResult eval(const TextQuery &t) const

  { return q->eval(t); }

 std::string rep() const { return q->rep(); }

private:

 Query(std::shared_ptr query): q(query) { }

 std::shared_ptr q;

};

Начнем с объявления дружественных операторов, создающих объекты класса Query. Эти операторы должны быть друзьями, чтобы использовать закрытый конструктор.

В открытом интерфейсе для класса Query объявляется, но еще не может быть определен получающий строку конструктор. Этот конструктор создает объект класса WordQuery, поэтому невозможно определить этот конструктор, пока не определен сам класс WordQuery.

Два других открытых члена представляют интерфейс для класса Query_base. В каждом случае оператор класса Query использует свой указатель класса Query_base для вызова соответствующей (виртуальный) функции класса Query_base. Фактически вызываемая версия определяется во время выполнения и будет зависеть от типа объекта, на который указывает указатель q.

Оператор вывода класса Query

Оператор вывода — хороший пример того, как работает вся система запросов:

std::ostream &

operator<<(std::ostream &os, const Query &query) {

 // Query::rep() осуществляет виртуальный вызов через свой

 // указатель Query_base на rep()

 return os << query.rep();

}

При выводе объекта класса Query оператор вывода вызывает (открытую) функцию-член rep() класса Query. Эта функция осуществляет виртуальный вызов через свой указатель-член функции-члена rep() объекта, на который указывает данный объект класса Query.

Query andq = Query(sought1) & Query(sought2);

cout << andq << endl;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных