class Shape
{
public:
virtual void draw(CWnd * window) = 0;//window - указатель на окно, в котором рисовать фигуру
virtual ~Shape(){};
};
Небольшой вопрос по проектированию
Абстрактный класс
Код:
Класс окна я создал следующим образом
Код:
class MyWnd
{
CWnd * pWnd;
public:
MyWnd(CWnd * Wnd):pWnd(Wnd){};
void draw(Shape & figure);
Point current();
Point current(Point p);
};
{
CWnd * pWnd;
public:
MyWnd(CWnd * Wnd):pWnd(Wnd){};
void draw(Shape & figure);
Point current();
Point current(Point p);
};
Реализация класса именно таким способом обусловлена тем, что за основу был взят проект MFC Application->Dialog Based, в котором автоматически уже создается объект типа CWnd, а мне остается только скопировать указатель на него в мой класс.
Теперь вопрос: может лучше было реализовать Shape как наследник MyWindow? Тогда не надо бы было каждый раз передавать указатель на окно, в котором рисовать. С другой стороны такой подход позволяет одну и ту же фигуру рисовать в любом существующем окне. Также интересен и ваш личный выбор в подобной ситуации, естественно желательно с аргументами :)
Если взять другой стандартный пример — «зоопарк», — то там всё становится более понятно.
Там есть абстрактный класс Животное, наследниками которого будут классы Змея и Медведь. У всех этих классов будет функция
virtual COLORREF Цвет(); // Цвет животного
Ешё пусть будет класс Клетка (в котором животное отбывает свой срок). У этого класса тоже есть функция
COLORREF Цвет(); // Цвет клетки
Может возникнуть желание наследовать
class Животное: public Клетка
Это желание надо подавить, потому что в классе Животное рано или поздно возникнет функция
virtual bool ПораКормить(); // true, если проголодалось
Эта функция для клетки не имеет смысла. Зато имеет смысл функция
bool ПораКрасить();
которая не имеет смысла для животного.
В вашем случае MyWnd = Клетка, Shape = Животное: каждый объект Shape "сидит в клетке" MyWnd, но при этом объекты Shape не являются объектами MyWnd. Эти объекты "чужды" друг другу. Поэтому наследование
class Shape: public MyWnd
сделать, конечно, можно, но не стоит.
Цитата:
Originally posted by sq_deep
Shape не должен быть наследником MyWnd. Наследование предполагает некую "родственность" объектов. Оно должно расширять или уточнять функциональность базового класса. В вашем случае это не очень видно из-за чрезмерной простоты примера и ещё потому, что как MyWnd, так и Shape — геометрические объекты.
Если взять другой стандартный пример — «зоопарк», — то там всё становится более понятно.
Там есть абстрактный класс Животное, наследниками которого будут классы Змея и Медведь. У всех этих классов будет функция
virtual COLORREF Цвет(); // Цвет животного
Ешё пусть будет класс Клетка (в котором животное отбывает свой срок). У этого класса тоже есть функция
COLORREF Цвет(); // Цвет клетки
Может возникнуть желание наследовать
class Животное: public Клетка
Это желание надо подавить, потому что в классе Животное рано или поздно возникнет функция
virtual bool ПораКормить(); // true, если проголодалось
Эта функция для клетки не имеет смысла. Зато имеет смысл функция
bool ПораКрасить();
которая не имеет смысла для животного.
В вашем случае MyWnd = Клетка, Shape = Животное: каждый объект Shape "сидит в клетке" MyWnd, но при этом объекты Shape не являются объектами MyWnd. Эти объекты "чужды" друг другу. Поэтому наследование
class Shape: public MyWnd
сделать, конечно, можно, но не стоит.
Shape не должен быть наследником MyWnd. Наследование предполагает некую "родственность" объектов. Оно должно расширять или уточнять функциональность базового класса. В вашем случае это не очень видно из-за чрезмерной простоты примера и ещё потому, что как MyWnd, так и Shape — геометрические объекты.
Если взять другой стандартный пример — «зоопарк», — то там всё становится более понятно.
Там есть абстрактный класс Животное, наследниками которого будут классы Змея и Медведь. У всех этих классов будет функция
virtual COLORREF Цвет(); // Цвет животного
Ешё пусть будет класс Клетка (в котором животное отбывает свой срок). У этого класса тоже есть функция
COLORREF Цвет(); // Цвет клетки
Может возникнуть желание наследовать
class Животное: public Клетка
Это желание надо подавить, потому что в классе Животное рано или поздно возникнет функция
virtual bool ПораКормить(); // true, если проголодалось
Эта функция для клетки не имеет смысла. Зато имеет смысл функция
bool ПораКрасить();
которая не имеет смысла для животного.
В вашем случае MyWnd = Клетка, Shape = Животное: каждый объект Shape "сидит в клетке" MyWnd, но при этом объекты Shape не являются объектами MyWnd. Эти объекты "чужды" друг другу. Поэтому наследование
class Shape: public MyWnd
сделать, конечно, можно, но не стоит.
спасибо, понял.