Мой вопрос относится к What's the point of IsA() in C++?. У меня есть критический код производительности, который содержит при определенном методе обработки определенных функций из производных классов, где доступен только базовый указатель. Каков наилучший способ проверить, какой производный класс у нас есть? Я закодировал два варианта, во втором варианте я мог бы удалить список Animal_type
и функцию get_type()
.Внедрить идентификатор для класса или использовать dynamic_cast
#include <iostream>
enum Animal_type { Dog_type, Cat_type };
struct Animal
{
virtual Animal_type get_type() const = 0;
};
struct Dog : Animal
{
void go_for_walk() const { std::cout << "Walking. Woof!" << std::endl; }
Animal_type get_type() const { return Dog_type; }
};
struct Cat : Animal
{
void be_evil() const { std::cout << "Being evil!" << std::endl; }
Animal_type get_type() const { return Cat_type; }
};
void action_option1(Animal* animal)
{
if (animal->get_type() == Dog_type)
dynamic_cast<Dog*>(animal)->go_for_walk();
else if (animal->get_type() == Cat_type)
dynamic_cast<Cat*>(animal)->be_evil();
else
return;
}
void action_option2(Animal* animal)
{
Dog* dog = dynamic_cast<Dog*>(animal);
if (dog)
{
dog->go_for_walk();
return;
}
Cat* cat = dynamic_cast<Cat*>(animal);
if (cat)
{
cat->be_evil();
return;
}
return;
}
int main()
{
Animal* cat = new Cat();
Animal* dog = new Dog();
action_option1(cat);
action_option2(cat);
action_option1(dog);
action_option2(dog);
return 0;
}
Вы оценили эффективность обоих подходов? – TartanLlama
Почему бы не использовать старую динамическую диспетчеризацию с виртуальными функциями? Кроме того, коммутация типов обычно считается огромным запахом кода. Вы считали посетителя, стратегию или шаблонный метод? – Jens
почему бы не иметь action_option1 и action_option2 как виртуальные на Animal и заставить их называть go_for_walk/be_evil? – paulm