Программирование. Принципы и практика использования C++ Исправленное издание, стр. 438
class Widget {// Класс Widget — это дескриптор класса Fl_widget,// а не сам класс Fl_widget;// мы пытаемся не смешивать наши интерфейсные классы с FLTKpublic: 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};Обратите внимание на то, что наш класс
WidgetWindowWidget WindowОбъект класса
Widgetlocwidthheightlabeldo_itWidgetmove()show()hide()attach()Класс
WidgetКласс
WidgetД.3. Реализация класса Window
Когда следует использовать указатели, а когда ссылки? Мы обсудили этот общий вопрос в разделе 8.5.6. Здесь мы лишь отметим, что некоторые программисты любят указатели и что нам нужны указатели, когда мы хотим сослаться на разные объекты в разные моменты времени.
До сих пор мы скрывали главный класс в нашей графической библиотеке — класс
WindowWindow.hclass Window : public Fl_Window {public: // позволяет системе выбрать место в памяти: 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()ShapeWindowdetach()WindowWindow::attach()attach()detach()Window.cpp