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

Поскольку вы уже прочитали главу 17, то вам должно быть очевидно, что аргумент Address должен иметь тип void*. И, разумеется, функция reference_to(addr) должна каким-то образом создавать ссылку на объект класса Simple_window из указателя addr, имеющего тип void*. Однако, если у вас нет опыта программирования, то ничто для вас не “очевидно” и не “разумеется”, пока вы не прочтете главу 17, поэтому рассмотрим и использование адресов подробнее.

Как описано в разделе A.17, язык C++ предлагает способ для указания имени типа. Рассмотрим пример.

typedef void* Address; // Address — это синоним типа void*

Это значит, что мы можем использовать имя Address вместо void*. В данном случае, используя имя Address, мы хотим подчеркнуть, что передаем адрес, и скрыть тот факт, что void* — это имя типа указателя на объект, тип которого неизвестен.

Итак, функция cb_next() получает указатель типа void* с именем addr в качестве аргумента и — каким-то образом — немедленно преобразовывает его в ссылку Simple_window&:

reference_to(addr)

Функция reference_to является шаблонной (раздел A.13).

templateW& reference_to(Address pw)

// интерпретирует адрес как ссылку на объект класса W

{

  return *static_cast(pw);

}

Здесь мы использовали шаблонную функцию, для того чтобы самостоятельно написать операции, действующие как приведение типа void* к типу Simple_window&. Это приведение типа static_cast описано в разделе 17.8.

Компилятор не имеет возможности проверить наши предположения о том, что аргумент addr ссылается на объект класса Simple_window, но правила языка требуют, чтобы компилятор в этом вопросе доверял программисту. К счастью, мы оказались правы. Об этом свидетельствует от факт, что система FLTK возвращает нам обратно указатель, который мы ей передавали. Поскольку, передавая указатель системе FLTK, мы знали его тип, можно использовать функцию reference_to, чтобы “получить его обратно”. Все это немного запутанно, не проходит проверку и не больше характерно для низкоуровневого программирования.

Получив ссылку на объект класса Simple_window, мы можем использовать ее для вызова функции-члена класса Simple_window. Рассмотрим пример (раздел 16.3).

void Simple_window::cb_next(Address, Address pw)

// вызов функции Simple_window::next() для окна,

// расположенного по адресу pw

{

  reference_to(pw).next();

}

Мы использовали довольно сложную функцию обратного вызова cb_next(), просто чтобы согласовать типы, необходимые для вызова совершенно обычной функции-члена next().

<p id="AutBody_Root715"><strong>Д.2. Реализация класса Widget</strong></p>

Наш интерфейсный класс Widget выглядит следующим образом.

class Widget {

// Класс Widget — это дескриптор класса Fl_widget,

// а не сам класс Fl_widget;

// мы пытаемся не смешивать наши интерфейсные классы с FLTK

public:

  Widget(Point xy, int w, int h, const string& s, Callback cb)

  :loc(xy), width(w), height(h), label(s), do_it(cb)

  { }

  virtual ~Widget() { } // деструктор

  virtual void move(int dx,int dy)

  { hide(); pw–>position(loc.x+=dx, loc.y+=dy); show(); }

  virtual void hide() { pw–>hide(); }

  virtual void show() { pw–>show(); }

  virtual void attach(Window&) = 0; // каждый объект класса

                                    // Widget определяет хотя бы

                                    // одно действие над окном

  Point loc;

  int width;

  int height;

  string label;

  Callback do_it;

protected:

  Window* own;   // каждый объект класса Widget

                 // принадлежит объекту классу Window

  Fl_Widget* pw; // каждый объект класса Widget о "своем"

                 // классе Fl_Widget

};

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

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

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

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

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

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

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

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

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