更改为使用dynamic_cast中的投射参考与投射指针

时间:2015-08-27 03:11:23

标签: c++ exception dynamic-cast

我有一个严重的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”是不是很奇怪?

1 个答案:

答案 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}}在子类中重写......