C++ 与强制转换指针相比,更改为在动态\u强制转换中使用强制转换引用
我有一系列的if-else-dynamic_-cast来执行downcast并执行如下特定的子类方法。我知道使用dynamic_cast可能会被认为是设计上的错误C++ 与强制转换指针相比,更改为在动态\u强制转换中使用强制转换引用,c++,exception,dynamic-cast,C++,Exception,Dynamic Cast,我有一系列的if-else-dynamic_-cast来执行downcast并执行如下特定的子类方法。我知道使用dynamic_cast可能会被认为是设计上的错误 void cryout(const Animal* pAnimal) { if(!pAnimal){ return; } ... if (auto pCat = dynamic_cast<const Cat*>(pAnimal)) { pCat->meow();
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";
}
}
}
但这种变化涉及到当非猫类动物对象传入时堆栈的展开。另外,堆栈展开可能会导致性能大幅下降。在我的案例中,这种参照铸造方法实用吗
顺便说一句,在正常的工作流程中抛出std::bad_cast异常不是很奇怪吗?如果没有上下文,解决方案是这样的:
#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);
}
但是,除非你别无选择,否则动物应该有一个纯虚拟函数cryout在子类中被重写…为什么不只使用dynamic_cast&Animal?dynamic_castanimla不推荐使用吗?@ChenOT如果你希望它经常失败,就不建议使用;例外情况应该只用于例外情况。在这种情况下,我并不认为这两种方法都是可取的,因为我更倾向于将cryout作为一种方法。但是,如果我一定要使用dynamic_cast,为了清晰起见,我更喜欢无异常版本。std::bad_cast异常抛出是表示转换引用失败的唯一方法,因此我想知道引用的dynamic_cast是否总是成功的,或者它将是一个例外情况。