当使用指针时,dynamic_cast 会在什么情况下抛出异常?

11

我在我的代码中使用 dynamic_cast 来将指针转换为以下的某个类型:

Base *base = here storing the pointer;

Derived *derived = dynamic_cast<Derived*>(base);

如果基类没有类层次结构的指针,则强制转换失败并返回NULL。在下面几行代码中,我检查了NULL。所以没有问题。

我遇到了一个崩溃转储,我的应用程序由于dynamic_cast引发异常而崩溃。

我知道只有在使用引用类型时,dynamic_cast才会抛出异常。

请问当我像上面的源代码一样使用指针时,dynamic_cast何时会抛出异常?enter image description here


什么会导致动态转换(dynamic cast)崩溃? - prasadmadanayake
2个回答

21
有想过使用指针作为上述源代码中所用的动态转换可能会抛出异常吗?
在一个定义良好的程序中,它不会。标准不允许:
"[C++11: 5.2.7/9]:一个指针类型的转换失败的值是所需结果类型的空指针值。 转换为引用类型失败将引发std :: bad_cast(18.7.2)异常。"
然而,如果您传递无效指针,则会引发未定义的行为,并且任何事情都可能发生,包括某些实现定义的C ++异常或运行时崩溃。

6

dynamic_cast<Derived*>可以抛出异常,如果传递给它的指针(base)是无效的,因为dynamic_cast需要解引用它才能知道其动态类型。

编辑:更明确地说。使用指针时,dynamic_cast永远不会抛出结构化异常(例如std::bad_cast),但是当传递一个无效指针时,它可能会抛出无结构异常,您无法捕获该异常。使用无效指针会导致未定义的行为,在这种情况下通常意味着访问无效内存并崩溃。

根据您在问题中附加的内存转储,很明显pInfo指向一个无效的对象,因此所有那些<Memory access error>消息。这意味着pInfo是一个无效的指针,这就是您的程序崩溃的原因。您的代码有漏洞,需要修复。


根据我的分析,我得知在无效指针的情况下会返回NULL。但是在某些情况下它可能会抛出异常而不是返回NULL。您能否给出有关此处无效指针的意义的意见? - srajeshnkl
@RajeshSubramanian 无效指针是指既不指向对象也不为 null 的指针。如果 base 指向一个已销毁的对象或未初始化为对象地址,则它是无效的。 - Gorpik
在我的情况下,从崩溃转储中我发现该对象不是空的;因为在这个转换之前我有一个检查空值的条件。 - srajeshnkl
该对象不为空。但它包含的一些成员值是不可访问的。这会导致 dynamic_cast 失败吗?我现在已经在我的实际问题中附上了 windbg 中该对象的监视窗口。(pInfo) 是传递给 dynamic_cast 的对象。 - srajeshnkl
一个对象永远不会是null;只有指针可以指向null。如果这些成员值“不可访问”,那就意味着它无效。是的,这将导致dynamic_cast失败。 - Gorpik
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接