Чтение онлайн

на главную - закладки

Жанры

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

Итак, функция

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

reference_to<Simple_window>(addr)

Функция

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

template<class W>W& reference_to(Address pw)

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

{

return *static_cast<W*>(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<Simple_window>(pw).next;

}

Мы использовали довольно сложную функцию обратного вызова

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

Д.2. Реализация класса Widget

Наш интерфейсный класс

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

};

Обратите внимание на то, что наш класс

Widget
следит за “своим” компонентом библиотеки FLTK и классом
Window
, с которыми он связан. Кроме того, отметьте, что для этого нам необходимы указатели, поскольку объект класса
Widget
на протяжении времени своего существования может быть связан с разными объектами класса
Window
. Ссылки или именованного объекта для этого недостаточно. (Объясните почему?)

Объект класса

Widget
имеет местоположение (
loc
), прямоугольную форму (
width
и
height
), а также сметку (
label
. Интересно, что он также имеет функцию обратного вызова (
do_it
), т.е. связывает образ объекта класса
Widget
на экране с фрагментом своего кода. Смысл операций
move
,
show
,
hide
и
attach
должен быть очевидным.

Класс

Widget
выглядит незаконченным. Он спроектирован как класс реализации, который пользователи не должны видеть слишком часто. Его стоит переделать. Мы подозреваем, что все эти открытые члены и “очевидные” операции содержат подводные камни.

Класс

Widget
имеет виртуальную функцию и может быть использован как базовый класс, поэтому в нем предусмотрен виртуальный деструктор (см. раздел 17.5.2).

Д.3. Реализация класса Window

Когда следует использовать указатели, а когда ссылки? Мы обсудили этот общий вопрос в разделе 8.5.6. Здесь мы лишь отметим, что некоторые программисты любят указатели и что нам нужны указатели, когда мы хотим сослаться на разные объекты в разные моменты времени.

До сих пор мы скрывали главный класс в нашей графической библиотеке — класс

Window
. Основная причина этого заключалась в том, что он использует указатели, а его реализация с помощью библиотеки FLTK опирается на использование свободной памяти. Вот как описан этот класса в заголовочном файле
Window.h
.

class Window : public Fl_Window {

public:

// позволяет системе выбрать место в памяти:

Поделиться:
Популярные книги

Адвокат Империи 3

Карелин Сергей Витальевич
3. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 3

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона

Вонгозеро

Вагнер Яна
1. Вонгозеро
Детективы:
триллеры
9.19
рейтинг книги
Вонгозеро

Ведьма Вильхельма

Шёпот Светлана
Любовные романы:
любовно-фантастические романы
8.67
рейтинг книги
Ведьма Вильхельма

Папина дочка

Рам Янка
4. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Папина дочка

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Как я строил магическую империю 7

Зубов Константин
7. Как я строил магическую империю
Фантастика:
попаданцы
постапокалипсис
аниме
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 7

Лучший из худший 3

Дашко Дмитрий
3. Лучший из худших
Фантастика:
городское фэнтези
попаданцы
аниме
6.00
рейтинг книги
Лучший из худший 3

Штурмовик из будущего 3

Политов Дмитрий Валерьевич
3. Небо в огне
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Штурмовик из будущего 3

Последний попаданец 2

Зубов Константин
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50
рейтинг книги
Последний попаданец 2

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье