与强制类型转换指针相比,在dynamic_cast中使用强制类型转换引用

Change to use casting reference in dynamic_cast compared to casting pointer

本文关键字:类型转换 cast 引用 指针 dynamic      更新时间:2023-10-16

我有很多if-else动态转换要向下转换,并执行特定的子类方法,如下所示。(我知道使用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";
        }
    }
}

但是这个改变涉及到当非猫动物对象传入时的堆栈展开。据我所知,堆栈展开可能会导致性能大幅下降。在我的情况下,这种参考方法实用吗?

BTW,是不是很奇怪,使"std::bad_cast异常"抛出在正常的工作流程?

给定很少的上下文,解决方案将是这样的:

 #include <iostream>
 #include <string>
 struct Animal
 {
     virtual ~Animal() {}    
 };
 struct Dog : Animal {
     void bark() const { std::cout << "barkn"; }
 };
 struct Cat : Animal {
     void meow() const { std::cout << "meown"; }
 };
 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应该有一个纯虚函数cryout()在子类中重写…