Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21

Частое использование dynamic_cast в конкретных целях. Правильно ли?

08.01.2014, 22:44. Показов 2939. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет, форум.
Гуманно ли использовать dynamic_cast вот в таких случаях?
Пример из подобных

- Есть библиотечный абстрактный класс Drawable.
Я наследую его, чтобы создавать разные геометрические объекты.
- Есть класс Polygon - используется как сцена. У него есть поле list<Drawable*> m_drawables и метод Add(Drawable* drawable).
Суть метода Add в том, что он рассчитывает наилучшую позицию для расположения фигуры и кидает его в полигон, т.е, записывает в m_drawables.

Не по теме:

Метод Update циклом прокручивает эти объекты, шагом вызывая метод api.Draw(*it)



Так вот, так как для разных фигур нужны разные расчёты, а я узнаю тип фигуры приведением типа(заодно и получаю доступы к методам конкретной фигуры) используя dynamic_cast.
Пример:
C++
1
2
3
4
5
6
7
8
9
void Add(Drawable* drawable)
{
...
    if (Parallelogram* pg = dynamic_cast<Parallelogram*>(drawable))
    {
        ...
    }
...
}
Это нормально или есть более лучший архитектурный подход?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.01.2014, 22:44
Ответы с готовыми решениями:

Использование dynamic_cast
#include&lt;iostream&gt; #include&lt;locale.h&gt; using namespace std; class Base { public: virtual void f() {}; }; class Der :...

Использование компонентов в коммерческих целях
Добрый вечер! У меня возник вопрос. Если я создам программу и там будут компоненты например. TMediaPlayer (Если проигрыватель музыки) ...

Использование static_cast и dynamic_cast между наследниками класса
Добрый день, Есть класс библиотеки QWT QwtScaleWidget. Я унаследуюсь от этого класса: #include &lt;qwt_scale_widget.h&gt; #include...

21
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
08.01.2014, 22:48
Цитата Сообщение от anonym17 Посмотреть сообщение
Это нормально или есть более лучший архитектурный подход?
А почему нет? Если результат вас удовлетворят - используйте.
0
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
08.01.2014, 22:51  [ТС]
Цитата Сообщение от xtorne21st Посмотреть сообщение
А почему нет? Если результат вас удовлетворят - используйте.
Просто часто ругаются на RTTI, вот почему спрашиваю.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
08.01.2014, 22:58
Цитата Сообщение от anonym17 Посмотреть сообщение
для разных фигур нужны разные расчёты
А нельзя ли, чтобы фигуры сами бы рассчитывали свои наилучшие позиции ?
RTTI не зря ругают, он не бесплатен. Я слышал, что в некоторых реализациях
RTTI реализован через сравнение строк...
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 23:06
такое решение плохо не столько производительностью, сколько плохой расширяемостью.
при появлении новой фигуры вы полезете изменять уже существующий код, что расходится с
Open/Close принципом или как там его.
0
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
08.01.2014, 23:06  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
А нельзя ли, чтобы фигуры сами бы рассчитывали свои наилучшие позиции ?
Но для этого нужно состояние полигона.
Вы предлагаете Parallelogram::Add(list<Drawable*>& drawables) или что?
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 23:14
если хочется поархитектурить - посмотрите в сторону паттерна Visitor.
вроде бы как раз ваш случай. будет без dynamic_cast но с расширением
тоже будет определенный геморрой.
dynamic_cast - вполне себе рабочий вариант. должен работать.
1
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
08.01.2014, 23:16
C++
1
2
3
4
void Polygon::Add(Drawable *pDrawable)
{
    pDrawable->CalculateBestPosition(this);
}
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 23:21
C++
1
2
3
4
void Polygon::Add(Drawable *pDrawable)
{
    pDrawable->CalculateBestPosition(this);
}
такой вариант - не айс.
Drawable связывается с неким Poligon который возможно так же наследник от Drawable.
тут взяли и засрали интерфейс. В результате все Drawable, которые могут быть и не фигурой
а скажем картинкой или еще хз чем, зависят от полигона в который они концептуально
не могут добавляться.
1
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
08.01.2014, 23:23  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
C++
1
2
3
4
void Polygon::Add(Drawable *pDrawable)
{
    pDrawable->CalculateBestPosition(this);
}
Drawable - библиотечный класс, я его менять не могу. Можно конечно сделать промежуточный класс, но тогда появляются другие проблемы с использованием его в Api данной библиотеки, снова тот же dynamic_cast.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 23:27
раз это библиотечный интерфейс - тогда приделать посетителя без прокси классов наверно не выйдет.
ну или я не знаю как. без динамического приведения тоже хз как сделать.
0
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
08.01.2014, 23:38  [ТС]
Всё таки надо архитектуру пересмотреть или же забить и использовать dynamic_cast?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
08.01.2014, 23:40
Цитата Сообщение от DU Посмотреть сообщение
такой вариант - не айс.
Drawable связывается с неким Poligon который возможно так же наследник от Drawable.
тут взяли и засрали интерфейс. В результате все Drawable, которые могут быть и не фигурой
а скажем картинкой или еще хз чем, зависят от полигона в который они концептуально
не могут добавляться.
Согласен. Просто как вариант на замену dynamic_cast.
Я просто содрогаюсь, представляя десятки этих кастов, и так для
каждого элемента в массиве... Бр-р!..
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 23:48
да при касте врятли что-то динамически выделяется. в сравнении с динамическим добавлением и рассчетами для оптимальной вставки - это копейки. у нас ведь тут добавление чего-то. и одна маленькая отрисовочка возможно затмит собой тысячи этих кастов.
0
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
09.01.2014, 00:06  [ТС]
Цитата Сообщение от DU Посмотреть сообщение
да при касте врятли что-то динамически выделяется. в сравнении с динамическим добавлением и рассчетами для оптимальной вставки - это копейки. у нас ведь тут добавление чего-то. и одна маленькая отрисовочка возможно затмит собой тысячи этих кастов.
А если использовать паттерн Visitor?
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
09.01.2014, 00:12
А если использовать паттерн Visitor?

раз это библиотечный интерфейс - тогда приделать посетителя без прокси классов наверно не выйдет.
ну или я не знаю как. без динамического приведения тоже хз как сделать.
0
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
09.01.2014, 00:29  [ТС]
Ну если введу промежуточный класс Depictable и буду все фигуры от него наследовать? Правда это сулит мне проблемы с самим Api библиотеки.
C++
1
2
3
4
class Depictable : public SomeLib::Drawable 
{
    ...
};
Какой вариант будет лучшим? Полиморфизм (виртуализация метода Add(Polygon* poligon)) или Visitor?
Или это вообще изначально плохой подход?
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
09.01.2014, 00:38
а вы и так и эдак попробуйте. будет вам опыт на будущее.
интерфейс добавления объектов в полигон остается одинаковым при обоих подходах.
так что то, как там все разруливается - деталь реализации.
с визитором однозначно более многословно все будет.
1
2 / 0 / 1
Регистрация: 31.10.2013
Сообщений: 21
09.01.2014, 06:08  [ТС]
Цитата Сообщение от DU Посмотреть сообщение
а вы и так и эдак попробуйте. будет вам опыт на будущее.
интерфейс добавления объектов в полигон остается одинаковым при обоих подходах.
так что то, как там все разруливается - деталь реализации.
с визитором однозначно более многословно все будет.
Примерно вот так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class Visitor;
 
class Depictable : public Lib::Drawable
{
public:
    ...
    void SetPosition(vector2f const& coord);
    virtual void accept(class Visitor*) = 0;
    ...
}
 
class Parallelogram : public Depictable
{
public:
    ...
    void accept(Visitor*);
    ...
}
 
void Parallelogram::accept(Visitor *v)
{
    v->visit(this);
}
 
class Visitor
{
    ...
  public:
    virtual void visit(Parallelogram*) = 0;
    ...
};
 
class CalcPositionVisitor : public Visitor
{
    ...
public:
    CalcPositionVisitor(Polygon* polygon) : m_polygon(polygon) {}
    virtual void visit(Parallelogram*);
private:
    Polygon* m_polygon;
    ...
};
 
class Polygon
{
    ...
public:
    void Add(Depictable* depictable);
private:
    std::list<Depicatble*> m_depicatbles;
    ...
};
 
void Polygon::Add(Depictable* depictable)
{
    CalcPositionVisitor calcPosition(this);
    depictable->accept(&calcPosition);
    depictable->SetPosition(calcPosition.getPosition());
    
    m_depicatbles.push_back(m_depictable);
}
0
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
09.01.2014, 15:17
Этот паттерн вообще не рекомендуют использовать... Его очень сложно сопровождать... Я не пойму чем вам dynamic_cast не нравится? Это простое и правильное решение, ИМХО
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.01.2014, 15:17
Помогаю со студенческими работами здесь

Наследование, dynamic_cast и использование последнего в связке с первым
Задание: написать отдалённую симуляцию интерфейса в виде консольного приложения, тоесть класс окно, в которое можно засовывать различные...

Использование пиратской версии в коммерчиских целях
Ну, собственно, из названии темы и следует вопрос, уже по собранному проекту возможно определить был ли он сделан в пиратке? А можно ли...

Использование формата BMP в коммерческих целях
Здравствуйте. Я где-то слышал, что формат BMP (bitmap) нельзя свободно использовать в своих программах, если планируется их...

Использование микрофона в игре в непредусмотренных целях
Я хочу с помощью C# перенести звук из видео (любого) в микрофон игры.Если есть какие то идеи , информация , темы , библиотеки , или вообще...

Использование голосовых сервисов Google в своих целях
Всем привет. Два вопроса тут возникло по теме топика: 1) Как известно легко можно использовать голосовой ввод от Google в своих целях. Я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru