我有一个严重的if-else dynamic_cast进行向下转换并执行如下的特定子类方法。 (我知道在设计中使用dynamic_cast可能会被认为是错误的。)
void cryout(const Animal* pAnimal)
{
if(!pAnimal){ return; }
...
if (auto pCat = dynamic_cast<const Cat*>(pAnimal))
{
pCat->meow();
}
else if (auto pDog = dynamic_cast<const Dog*>(pAnimal))
{
pDog->bark();
}
else
{
std::cerr << "No such animal.\n" ;
}
}
然后我想改变让参数传递的参数不用担心空指针问题。
void cryout(const Animal& animal)
{
...
try
{
auto& cat = dynamic_cast<const Cat&>(animal);
cat.meow();
}
catch (std::bad_cast)
{
try
{
auto& dog = dynamic_cast<const Dog&>(animal);
dog.bark();
}
catch (std::bad_cast)
{
std::cerr << "No such animal.\n";
}
}
}
但是当非猫动物对象传入时,这种变化涉及堆栈展开.AFAIK,堆栈展开可能会导致性能下降很多。在我的案例中,这种参考方法是否实用?
顺便说一句,在正常工作流程中抛出“std :: bad_cast exception”是不是很奇怪?答案 0 :(得分:0)
鉴于上下文很少,解决方案将是这样的:
#include <iostream>
#include <string>
struct Animal
{
virtual ~Animal() {}
};
struct Dog : Animal {
void bark() const { std::cout << "bark\n"; }
};
struct Cat : Animal {
void meow() const { std::cout << "meow\n"; }
};
void cryout(const Animal& pAnimal)
{
if (auto pCat = dynamic_cast<const Cat*>(&pAnimal))
{
pCat->meow();
}
else if (auto pDog = dynamic_cast<const Dog*>(&pAnimal))
{
pDog->bark();
}
else
{
std::cerr << "No such animal.\n" ;
}
}
int main()
{
Cat c;
cryout(c);
Dog d;
cryout(d);
}
但除非你 没有 选择 - Animal
应该有一个纯虚函数{ {1}}在子类中重写......