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); 编译通过,运行报错。请问这样用为什么不对??

解决方案 »

  1.   

    CBase* pBase = new CBase;
    这句话将按CBase类给pBase分配的空间,
    这显然不满足 CA* 类型的要求,如果改成 CBase* pBase = new CA;
    把pBase声明成CBase*类型的,但空间分配是按照CA类的
    dynamic_cast<CA*>会成功测试环境 Dev-Cpp 4990 通过
      

  2.   

    dynamic_cast,它被用于安全地沿着类的继承关系向下进行类型转换
      

  3.   

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

  4.   

    dynamic_cast转换后一般调用virtual函数才安全
      

  5.   

    同意,oyljerry得说法,应为pA所指得对象还是CBase对象,对象里面得vtbl还是指向CBase得vTbl,所以调用 virtual不会出错,但是调用SetA()肯定出错,应为CBase对象里面根本就没有m_a这个部分,还是一句老话对象布局错误。