Chinaunix

标题: 这个dynamic_cast不能抛出异常,而是崩溃了!!!! [打印本页]

作者: jeanlove    时间: 2009-02-01 14:27
标题: 这个dynamic_cast不能抛出异常,而是崩溃了!!!!
如题,我写了下面这个程序,测试dynamic_cast错误处理的情况
#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>
using namespace std;
class A{
public:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int x;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual void fa(){}
};
class B{
public:
&nbsp;&nbsp;&nbsp;&nbsp;int y;
&nbsp;&nbsp;&nbsp;&nbsp;//virtual void foo(){}

};
class D:public B{
public:
&nbsp;&nbsp;&nbsp;&nbsp;int z;
};
int main(int argc, char *argv[]){
&nbsp;&nbsp;&nbsp;&nbsp;B* pb=new B();
&nbsp;&nbsp;&nbsp;&nbsp;B& rb=*pb;
&nbsp;&nbsp;&nbsp;&nbsp;try{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//D& rd =dynamic_cast<D&>(rb);//本语句会抛出std::bad_cast

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A* pa=(A*)pb;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D* pd=dynamic_cast<D*>(pa);
&nbsp;&nbsp;&nbsp;&nbsp;}catch(std::bad_cast){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("std::bad_cast\n");
&nbsp;&nbsp;&nbsp;&nbsp;}catch(...){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("get other exception\n");
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;//system("PAUSE");

&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}


我期望pa被dynamic_cast转型的时候,能抛出某种异常,但是实际上程序崩溃了。
=====================================================
我的环境是winxp+devcpp4992,是gcc/gdb的集成环

>gcc --version
gcc (GCC) 3.4.2 (mingw-special)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

请dx帮忙解释一下,10分感谢!

[ 本帖最后由 jeanlove 于 2009-2-1 14:28 编辑 ]
作者: emacsnw    时间: 2009-02-01 14:27
原帖由 jeanlove 于 2009-1-31 22:43 发表

谢谢,但是有点不明白的地方,就是我之前
D& rd =dynamic_cast(rb);
这句话是可以成功抛出异常的,这是不是说明异常处理的功能已经启用了呢????


我觉得崩溃时因为你前面的那个c-style cast使得RTTI寻找对象的类层次时候访问内存越界导致的。
作者: wwwsq    时间: 2009-02-01 14:32
GCC编译选项

/GX[-] 启用 C++ 异常处理(与 /EHsc 相同) enable C++ EH (same as /EHsc)
/EHs 启用同步 C++ 异常处理 enable synchronous C++ EH
/EHa 启用异步 C++ 异常处理 enable asynchronous C++ EH

from: http://www.cppblog.com/mydriverc/articles/33144.html


从我的经验来说,我建议尽量不要在C++里面使用异常。

[ 本帖最后由 wwwsq 于 2009-2-1 14:38 编辑 ]
作者: jeanlove    时间: 2009-02-01 14:43
原帖由 wwwsq 于 2009-2-1 14:32 发表
GCC编译选项

/GX[-] 启用 C++ 异常处理(与 /EHsc 相同) enable C++ EH (same as /EHsc)
/EHs 启用同步 C++ 异常处理 enable synchronous C++ EH
/EHa 启用异步 C++ 异常处理 enable asynchronous C++ E ...

谢谢,但是有点不明白的地方,就是我之前
D& rd =dynamic_cast<D&>(rb);
这句话是可以成功抛出异常的,这是不是说明异常处理的功能已经启用了呢????
作者: bezd    时间: 2009-02-01 14:51
2楼的方法可行不???我也遇到这种问题了,只不过我的数据环境比较复杂,不会每次都暴掉,大概一两个月崩一次。因为我是引用静态库里面的函数,也用了try,跟踪到调用的函数后就没法跟踪了
  try{   
      ...//中间调用静态库函数,崩溃了
   }catch(...){   
        ....//出错了   
  }

[ 本帖最后由 bezd 于 2009-2-1 15:10 编辑 ]
作者: jeanlove    时间: 2009-02-01 15:33
原帖由 emacsnw 于 2009-2-1 15:20 发表


我觉得崩溃时因为你前面的那个c-style cast使得RTTI寻找对象的类层次时候访问内存越界导致的。

我把B加上了那个virtual的关键字,似乎就不会崩溃了。感觉这个解释最贴切,还是要给分的!
作者: bruceteen    时间: 2009-02-01 15:45
因为
1. rb的静态类型是class  B
2. class B不包含任何virtual函数
所以我觉得
D& rd =dynamic_cast<D&>(rb);
在逻辑上,本身就讲不通。
class B不是一个动态类型时,即没有人会写出 B* p = new D 这样的语句,自然也就不存在 dynamic_cast<D&>(rb);
作者: bidongliang    时间: 2009-02-01 15:59
如果针对指针类型的dynamic_cast失败,则结果是0, 如果针对引用类型的dynamic_cast失败,则抛出一个异常.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2