C++ 使用带有引用和指针的 dynamic_cast 时的行为差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1276847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:25:39  来源:igfitidea点击:

Difference in behavior while using dynamic_cast with reference and pointers

c++castingdynamic-cast

提问by Naveen

I was checking the behavior of dynamic_cast and found that when it fails, std::bad_cast exception is thrown only if the destination is a reference type. If the destination is a pointer type then no exception is thrown from the cast. This is my sample code:

我正在检查 dynamic_cast 的行为,发现当它失败时,只有当目标是引用类型时才会抛出 std::bad_cast 异常。如果目标是指针类型,则不会从强制转换中抛出异常。这是我的示例代码:

class A
{
    public:
        virtual ~A()
        {
        }
};

class B : public A
{
};

int  main()
{
    A* p = new A;

    //Using reference
    try
    {
    B& b = dynamic_cast<B&>(*p);
    }
    catch(std::bad_cast exp)
    {
    std::cout<<"Caught bad cast\n";
    }

    //Using pointer
      try
    {
    B* pB = dynamic_cast<B*>(p);

    if( pB == NULL)
    {
        std::cout<<"NULL Pointer\n";
    }
    }
    catch(std::bad_cast exp)
    {
    std::cout<<"Caught bad cast\n";
    }

    return 0;
}

Output is "Caught bad cast" and "NULL pointer". Code is compiled using VS2008. Is this the correct behavior ? If yes, then why there is a difference?

输出是“Caught bad cast”和“NULL pointer”。代码使用VS2008编译。这是正确的行为吗?如果是,那么为什么会有差异?

回答by sharptooth

Yes, this is correct behaviour. The reason is that you can have a null pointer, but not a null reference - any reference has to be bound to an object.

是的,这是正确的行为。原因是你可以有一个空指针,但不能有一个空引用——任何引用都必须绑定到一个对象。

So when dynamic_cast for a pointer type fails it returns a null pointer and the caller can check for that, but when it fails for a reference type it can't return a null reference, so an exception is the only reasonable way to signal a problem.

因此,当指针类型的 dynamic_cast 失败时,它返回一个空指针,调用者可以检查它,但是当引用类型失败时,它不能返回空引用,因此异常是唯一合理的发出问题信号的方法.

回答by Naveen

See the C++ Standard, section 5.2.7/9:

请参阅 C++ 标准,第 5.2.7/9 节:

9 The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throws bad_cast (18.5.2).

9 转换为指针类型失败的值是所需结果类型的空指针值。失败的引用类型转换会抛出 bad_cast (18.5.2)。

As to why - these are Stroustrup's words from the D & E book, section 14.2.2:

至于为什么 - 这些是 Stroustrup 在 D & E 书中的话,第 14.2.2 节:

I use a reference cast when I want an assumption about a reference type checked and consider it a failure for my assumption to be wrong. If instead I want to select among plausible alternatives, I use a pointer cast and test the result.

当我想要检查关于引用类型的假设并认为我的假设是错误的失败时,我使用引用强制转换。相反,如果我想在合理的替代方案中进行选择,我会使用指针转换并测试结果。

回答by AProgrammer

Yes, 5.2.7/9

是的,5.2.7/9

The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throws bad_cast (18.5.2).

转换为指针类型失败的值是所需结果类型的空指针值。失败的引用类型转换会抛出 bad_cast (18.5.2)。

回答by Kim Gr?sman

Yes, it is. Because dynamic_castcan't return NULL for a failed reference cast, an exception is the only way out.

是的。因为dynamic_cast不能为失败的引用转换返回 NULL,所以异常是唯一的出路。

That is, a reference can't be NULL, so there is nothing suitable to return.

也就是说,引用不能为 NULL,因此没有什么适合返回。