Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:
Window(int w, int h, const string& title);
// верхний левый угол в точке xy:
Window(Point xy, int w, int h, const string& title);
virtual ~Window { }
int x_max const { return w; }
int y_max const { return h; }
void resize(int ww, int hh) { w=ww, h=hh; size(ww,hh); }
void set_label(const string& s) { label(s.c_str); }
void attach(Shape& s) { shapes.push_back(&s); }
void attach(Widget&);
void detach(Shape& s); //
удаляет элемент w из фигур
void detach(Widget& w); // удаляет элемент w из окна
// (отключает обратные вызовы)
void put_on_top(Shape& p); // помещает объект p поверх
// всех других фигур
protected:
void draw;
private:
vector<Shape*> shapes; // фигуры связываются с окном
int w,h; // размер окна
void init;
};
Итак, когда мы связываем фигуру с окном, используя функцию
attach
, мы храним указатель в объектах класса Shape
, поэтому объект класса Window
может рисовать соответствующую фигуру. Поскольку впоследствии мы можем отсоединить фигуру от окна с помощью функции detach
, поэтому нам нужен указатель. По существу, присоединенная фигура принадлежит своему коду; мы просто передаем объекту класса Window
ссылку на нее. Функция Window::attach
преобразовывает свой аргумент в указатель, чтобы его можно было сохранить. Как показано выше, функция attach
является тривиальной; функция detach
немного сложнее. Открыв файл Window.cpp
, мы видим следующее.
void Window::detach(Shape& s)
// определяет, что первой должна быть удалена
// последняя присоединенная фигура
{
for (unsigned int i = shapes.size; 0<i; ––i)
if (shapes[i–1]==&s) shapes.erase(&shapes[i–1]);
}
Функция-член
erase
удаляет (стирает) значение из вектора, уменьшая его размер на единицу (раздел 20.7.1). Класс Window
используется как базовый, поэтому он содержит виртуальный деструктор (раздел 17.5.2). Д.4. Реализация класса Vector_ref
По существу, класс
Vector_ref
имитирует вектор ссылок. Мы можем инициализировать его ссылками или указателями. • Если объект передается объекту класса
Vector_ref
с помощью ссылки, то предполагается, что он принадлежит вызывающей функции, которая управляет его временем жизни (например, объект — это переменная, находящаяся в определенной области видимости). • Если объект передается объекту класса
Vector_ref
с помощью указателя, то предполагается, что он размещен в памяти с помощью оператора new
, а ответственность за его удаление несет класс Vector_ref
. Элемент хранится в объекте класса
Vector_ref
в виде указателя, а не как копия объекта, и имеет семантику ссылок. Например, можно поместить в вектор класса Vector_ref<Shape>
объект класса Circle
, не подвергаясь опасности срезки.
template<class T> class Vector_ref {
vector<T*> v;
vector<T*> owned;
public:
Vector_ref {}
Vector_ref(T* a, T* b = 0, T* c = 0, T* d = 0);
~Vector_ref { for (int i=0; i<owned.size; ++i)
delete owned[i]; }
void push_back(T& s) { v.push_back(&s); }
void push_back(T* p) { v.push_back(p); owned.push_back(p); }
T& operator[](int i) { return *v[i]; }
const T& operator[](int i) const { return *v[i]; }
int size const { return v.size; }
};
Деструктор класса
Vector_ref
удаляет каждый объект, переданный ему как указатель. Д.5. Пример: манипулирование объектами класса Widget
Это законченная программа. Она демонстрирует многие из свойств классов
Widget/Window
. Мы поместили в нее минимальное количество комментариев. К сожалению, такое недостаточное комментирование программ — довольно распространенное явление. Попытайтесь выполнить эту программу и объяснить, как она работает.
#include "../GUI.h"
using namespace Graph_lib;
class W7 : public Window {
// четыре способа продемонстрировать, что кнопка может
// передвигаться:
// показать/скрыть, изменить местоположение, создать новую
// и присоединить/отсоединить
public:
W7(int n, int n, const string& t);
Button* p1; // показать/скрыть
Button* p2;
bool sh_left;
Button* mvp; // переместить
bool mv_left;
Button* cdp; // создать/уничтожить
bool cd_left;
Button* adp1; // активировать/деактивировать
Button* adp2;
bool ad_left;
void sh; // действия
Поделиться:
Популярные книги
Камень Книга седьмая
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Барон диктует правила
4. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ты не мой BOY
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Дворянская кровь
1. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Неверный
Любовные романы:
современные любовные романы
5.50
рейтинг книги
Не грози Дубровскому! Том V
5. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сердце Дракона. Том 19. Часть 1
19. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.52
рейтинг книги
Мама для дракончика или Жена к вылуплению
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Ваше Сиятельство 3
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Снегурка для опера Морозова
4. Опасная работа
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Архил...?
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Идеальный мир для Социопата 2
2. Социопат
Фантастика:
боевая фантастика
рпг
6.11
рейтинг книги
Внешняя Зона
8. Real-Rpg
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Идеальный мир для Лекаря 16
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00