std::bad_cast 指针与参考情况

发布于 2025-01-08 19:16:20 字数 516 浏览 0 评论 0原文

我注意到关于 std::bad_cast 异常,引用和指针的行为似乎不一样。例如:

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

//Case #1
int main()
{
    A a;
    B& b = dynamic_cast<B&>(a);  //Would throw std::bad_cast.
}

//Case #2
int main()
{
    A* a = new A;
    B* b = dynamic_cast<B*>(a);  //Would not throw std::bad_cast.
}

在第一种情况下,会生成 std​​::bad_cast 异常,而在第二种情况下不会生成异常 - 相反,b 指针只是被赋予值 NULL。

有人可以向我解释为什么当两者都是 bad_cast 示例时只有前者抛出异常吗?我认为这个决定背后有一个很好的动机,但我误用了一些东西,因为我不理解这个动机。

I've noticed with regard to the std::bad_cast exception that references and pointers don't seem to act the same way. For example:

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

//Case #1
int main()
{
    A a;
    B& b = dynamic_cast<B&>(a);  //Would throw std::bad_cast.
}

//Case #2
int main()
{
    A* a = new A;
    B* b = dynamic_cast<B*>(a);  //Would not throw std::bad_cast.
}

In the first case, an exception of std::bad_cast is generated, and in the second case no exception is generated - instead, the b pointer just is assigned the value NULL.

Can someone explain to me why only the former throws an exception when both are bad_cast examples? I figure there's a good motive behind the decision, and that I'm misusing something as I don't understand that motivation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

衣神在巴黎 2025-01-15 19:16:20

有人可以向我解释一下为什么只有前者会抛出异常吗?

这就是 dynamic_cast 被指定的行为方式:涉及指针的错误 dynamic_cast 会产生空指针,但没有空引用,因此错误的 dynamic_cast > 涉及引用会引发 bad_cast

事实上,涉及指针的失败 dynamic_cast 会产生空指针,这一事实很有用,因为它允许进行更清晰、更简单的类型检查,并允许使用以下惯用法:

if (B* b = dynamic_cast<B*>(a))
{
    // The dynamic_cast succeeded and 'b' is non-null.
}

使用此惯用法,b 是当且仅当它非空时在范围内且可用。

Can someone explain to me why only the former throws an exception?

That is how dynamic_cast is specified to behave: a bad dynamic_cast involving pointers yields a null pointer, but there are no null references, so a bad dynamic_cast involving references throws a bad_cast.

The fact that a failed dynamic_cast involving pointers yields a null pointer is useful because it allows for cleaner, simpler type checking and allows for the following idiom:

if (B* b = dynamic_cast<B*>(a))
{
    // The dynamic_cast succeeded and 'b' is non-null.
}

With this idiom, b is in scope and usable if and only if it is non-null.

逐鹿 2025-01-15 19:16:20

引用必须绑定到包含有效内存地址的对象...它们不能“未初始化”,也没有默认的非绑定初始化值。请注意,C++11 标准中的第 8.5/8 节指出,

调用引用类型实体的默认初始化或值初始化的程序格式不正确。

另一方面,指针变量只是内存地址,其中包含指向其他内存地址的值,因此可以具有 NULL 值。

因此,如果按照标准,dynamic_cast 操作必须返回一个有效的内存地址来绑定到引用变量,那么如果动态转换失败,它就不能返回“非值” “...唯一的选择是抛出异常。

References must be bound to an object that contains a valid memory address ... they cannot be "uninitialized", nor do they have a default non-bound initialization values. Note that section 8.5/8 in the C++11 standard states,

A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.

Pointer variables on the other-hand are just memory addresses that contain values that point to other memory addresses and therefore can have a NULL value.

So if by the standard the dynamic_cast<T&> operation must return a valid memory address to bind to the reference variable, then if the dynamic cast fails, it can't return a "non-value" ... the only option is to throw an exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文