M>что быстрее: switch (p->GetType()) или последовательный if (MessageClick* p2 = dynamic_cast<MessageClick*>(p)){} else if... M>Кто-нибудь знает насколько быстро работает dynamic_cast по сравнению с вызовом виртуальной функции?
Вообще, это некорректный вопрос. Для разных компиляторов значения будут разными. В принципе, можно ожидать, что switch будет быстрее. Например, для MSVC++7.0, если вызов функции принять за единицу, числа примерно такие:
Однако, следует заметить, что, за редким исключением, вместо поиска лучшего typeid следует пересмотреть дизайн приложения. Для большинства реальных приложений скорость выполнения инструкции dynamic_cast вполне адекватна. Кроме того, "самопальные" решения для RTTI в большинстве случаев не могут учесть многих тонкостей и, как следствие, обычно ведут к снижению надежности и/или ухудшению общего дизайна приложения.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
class IMessage
{
public:
virtual int GetType() const = 0;
};
class MessageClick
{
public:
virtual int GetType() const {return MT_CLICK;}
};
А потом в коде нужно, имея IMessage, узнать тип сообщения и привести его к этому типу. Так вот встал вопрос:
что быстрее: switch (p->GetType()) или последовательный if (MessageClick* p2 = dynamic_cast<MessageClick*>(p)){} else if...
Кто-нибудь знает насколько быстро работает dynamic_cast по сравнению с вызовом виртуальной функции?
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Для большинства реальных приложений скорость выполнения инструкции dynamic_cast вполне адекватна.
Да вполне. Просто хочу добавить что тут зависит от того что к чему приводиться производный тип к базовому или наоборот. Если производный к базовому, то dynamic_cast просто возвращает указатель на производный класс, а вот если наоборот, то тут идет сравнение RTTI по полной программе и скорость такого приведения значительно снижается.
M>А потом в коде нужно, имея IMessage, узнать тип сообщения и привести его к этому типу. Так вот встал вопрос: M>что быстрее: switch (p->GetType()) или последовательный if (MessageClick* p2 = dynamic_cast<MessageClick*>(p)){} else if... M>Кто-нибудь знает насколько быстро работает dynamic_cast по сравнению с вызовом виртуальной функции?
Я бы спрашивал насколько медленно. Механизм виртуальных функции работает быстрее.
Но я бы на этом не останавливался. Ударьте полиморфизмом по switch в клиентском классе:
void OnMessage( const IMessage& Msg)
{
// обработка по умолчанию — аналог default в switch
// обычно ничего не делается
}
Здравствуйте Павел Кузнецов, Вы писали:
ON>>(...) Ударьте полиморфизмом по switch в клиентском классе: ON>>void OnMessage( const IMessage& Msg) ... ON>>void OnMessage( const MessageClick& ClickMsg) ...
ПК><pedantic> ПК>В своем сообщении маэстро, говоря о полиморфизме, привел пример перегрузки функций. ПК></pedantic>
И правильно сделал. Сие есть частный случай полиморфизма. А то, что в школе учат, что полиморфизм суть наличие ключевого слова виртуал в языке — так это неправда. Это они от незнания.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
ПК>>В своем сообщении маэстро, говоря о полиморфизме, привел пример перегрузки функций. S>И правильно сделал. Сие есть частный случай полиморфизма. А то, что в школе учат, что полиморфизм суть наличие ключевого слова виртуал в языке — так это неправда. Это они от незнания.
Вообще говоря, конечно, перегрузка является разновидностью полиморфизма. Однако, в объектно-ориентированном программировании вообще, и в C++ в частности, для избежания неоднозначности, говоря о статическом полиморфизме принято указывать это явно; просто полиморфизм принято ассоциировать с динамическим связыванием. Более того, в стандарте языка С++ вводится понятие полиморфных объектов (объекты классов, имеющих виртуальные функции). Поэтому, в контексте C++, IMHO, использование термина полиморфизм для обозначения перегрузки функций вносит ненужную путаницу.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте OlegN, Вы писали: ON>Но я бы на этом не останавливался. Ударьте полиморфизмом по switch в клиентском классе:
Я б тоже не останавливался, да нельзя. Поскольку количество подклассов IMessage заранее не известно и события отправляются в абстрактный класс с одним методом SendMessage(IMessage*), который потом кто-то перегружает.
Здравствуйте Mishka, Вы писали:
M>Поскольку количество подклассов IMessage заранее не известно и события отправляются в абстрактный класс с одним методом SendMessage(IMessage*), который потом кто-то перегружает.
Здравствуйте Anton V. Kolotaev, Вы писали:
AVK>Здравствуйте Mishka, Вы писали:
M>>Поскольку количество подклассов IMessage заранее не известно и события отправляются в абстрактный класс с одним методом SendMessage(IMessage*), который потом кто-то перегружает.
AVK>А не пахнет ли здесь паттерном посетитель?