У меня есть иерархия классов геометрических фигур:
struct Figure {
virtual void draw_figure() = 0;
}
struct Circle : Figure {
Circle(int radius);
void draw_figure();
void set_radius(int radius);
}
В коде для отрисовки все фигуры представлены вектором Figure*
, чтобы вызывать draw_figure()
динамически. Но что если я хочу после создания круга изменить его радиус?
Figure* circle = new Circle(42);
circle -> set_radius(21);
Так это не получается сделать. Подскажите, как правильно действовать в такой ситуации. Добавлять set_radius
в Figure
нелогично, т.к. не всякой фигуре нужен этот метод, а делать dynamic_cast
скорее хак, чем нормальное решение.
Подойдем к задаче с другой стороны. Наверно, вряд ли Вы хотите просто поменять радиус у одной произвольной фигуры (не круга, а фигуры). И более того, если уж так случилось, то код, который меняет радиус, знает, что это круг. Либо, код, который меняет радиус, на самом деле меняет размер фигуры.
А теперь уже и решение появляется. Можно в класс фигуры добавить виртуальную функцию "изменить размер". Для круга она будет менять радиус, для квадрата сторону. И так далее (для прямоугольника может менять диагональ, а стороны - пропорционально).
И есть второй случай. Добавлять новую функцию в класс (менять интерфейс базового класса) не хочется. В этом случае поможет паттерн визитор и на хабре есть статья. Этот паттерн поможет решить такую задачу "увеличить размеры всех моих фигур".
Используйте CRTP в таких ситуациях.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как правильно использовать контейнер set, состоящий из класса и компаратора? Написала код, но выдает очень много ошибокПример: Как выглядит...
На сайте Microsoft, есть статья, как привязать Google test к VS: ссылкаВыполнив начальный этап, а именно установка адаптера для этих тестов, я пробую...
Подскажите как отсортировать список по имени, фамилии и году
Захотел научиться программировать на C++Скачал CodeLite, создал workspace, new project и скопировал текст программы "Hellow world!" в новый файл