У меня есть иерархия классов геометрических фигур:
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 в таких ситуациях.
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники