dynamic_cast

class CBase
{
public:
int m_base;
void SetBase()
{
m_base = 5;
cout<<m_base<<endl;
}
virtual void func()
{}
};

class CA:public CBase
{
public:
int m_a;
void SetA()
{
m_a = 6;
cout<<m_a<<endl;
}
virtual void func()
{
cout<<"CA"<<endl;
}
};

class CB:public CBase
{
public:
int m_b;
void SetC()
{
m_b = 7;
cout<<m_b<<endl;
}
virtual void func()
{
cout<<"CB"<<endl;
}
};

void main()
{
CBase* pBase = new CBase;
pBase->SetBase();
CA* pA = dynamic_cast<CA*>(pBase); //用static_cast没问题
if(pA)
{
pA->SetA();
cout<<"the address of pBase"<<(long)pBase<<endl;
cout<<"the address of pA"<<(long)pA<<endl;
}
}
CA* pA = dynamic_cast<CA*>(pBase); 编译通过,运行报错。请问这样用为什么不对??


回复人:longj(大哥雁)  三级(初级)  信誉:98      2004-12-17 12:00:17  得分:20

CBase* pBase = new CBase;
这句话将按CBase类给pBase分配的空间,
这显然不满足 CA* 类型的要求,

如果改成 CBase* pBase = new CA;
把pBase声明成CBase*类型的,但空间分配是按照CA类的
dynamic_cast<CA*>会成功

测试环境 Dev-Cpp 4990 通过
TOP
回复人:MZP(mzp)  五级(中级)  信誉:99      2004-12-17 12:18:18  得分:10

基类不能强转为继承类,反之可以。
TOP
回复人:hjunxu(hjun)  一星(中级)  信誉:106      2004-12-17 12:24:59  得分:10

如楼上所说。基类强转成派生类是危险的。
TOP
回复人:oyljerry(☆勇敢的心☆→㊣Set to work㊣)  两星(中级)  信誉:120      2004-12-17 12:28:57  得分:20

dynamic_cast,它被用于安全地沿着类的继承关系向下进行类型转换
TOP
回复人:blizzardinto(董)  一级(初级)  信誉:97      2004-12-17 12:37:39  得分:20

虽然 基类指针转换成派生类是危险的,但是有时候是必须的,而dynamic_cast和static_cast只是为向下转型而设计的操作符,用这两个操作符是你自己的心里很清楚,基类的指针所指的到底是什么类型,MFC比如CreateObject()返回的是CObject的指针,但是通常指向的都是它的子类对象,如CWnd所以这个时候你就可以CWnd* pWnd = dynamic_cast<CWnd*>(pObject),应为你能确认本次调用pObject实际指向的是个CWnd对象,如果你不能确认它的类型还这样转化,肯定会导致运行错误。(应为不同的类型对象的布局不一样)
参考文献《Inside C++ Object Module》(有空看看)
TOP
回复人:oyljerry(☆勇敢的心☆→㊣Set to work㊣)  两星(中级)  信誉:120      2004-12-17 12:42:27  得分:10

dynamic_cast转换后一般调用virtual函数才安全
TOP
回复人:blizzardinto(董)  一级(初级)  信誉:97      2004-12-17 12:51:07  得分:10

同意,oyljerry得说法,应为pA所指得对象还是CBase对象,对象里面得vtbl还是指向CBase得vTbl,所以调用 virtual不会出错,但是调用SetA()肯定出错,应为CBase对象里面根本就没有m_a这个部分,还是一句老话对象布局错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值