Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与强制转换指针相比,更改为在动态\u强制转换中使用强制转换引用_C++_Exception_Dynamic Cast - Fatal编程技术网

C++ 与强制转换指针相比,更改为在动态\u强制转换中使用强制转换引用

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();

我有一系列的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();
    }
    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是否总是成功的,或者它将是一个例外情况。