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); 编译通过,运行报错。请问这样用为什么不对??
{
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这个部分,还是一句老话对象布局错误。 |