dynamic_cast仅用于对象的指针和引用,它确保类型转换记过是一个完全合法的请求类对象。
因此,dynamic_cast在转换一个类到一个其基类的时候,总是成功:
class CBase{ };
class CDerived:public CBase{ };
CBase b; CBase* pb;
CDerived d; CDerived* pd;
pb = dynamic_cast<CBase*>(&d); // ok:derived-to-base
pd = dynamic_cast<CDerived*>(&b); // wrong:base-to-derived
在此程序片段中的第二个转换会产生一个编译错误,因为在dynamic_cast中基类到继承类转换是不允许的,除非基类是多态的。
那下面例子只要在基类中添加一个虚函数,基类就支持多态了:
class CBase
{
public:
virtual void test(){};
};
class CDerived:public CBase
{
};
int main()
{
CBase *b= new CDerived();
CBase *pb;
CDerived d;
CDerived* pd;
pb = dynamic_cast<CBase *>(&d);
pd = dynamic_cast<CDerived *>(b);
}
这样,pd = dynamic_cast<CDerived *>(b);从基类转换到继承类就能成功。这就是c++多态的魅力所在(更详细的理解,请参考侯捷老师翻译的《深度探索C++对象模型》,你会在里面找到所有的答案)!
再看一个多继承的例子:
class Animal {public: virtual ~Animal(){}; int m1; };
class Creature {public: virtual ~Creature(){}; int m2; };
class Bird:public Animal, public Creature { };
int main()
{
Bird *bird = new Bird;
Creature *creature = dynamic_cast<Creature *>(bird);//case 1
Animal *animal = dynamic_cast<Animal *>(creature);//case 2
Creature *creature1 = new Creature;
Animal *animal1 = dynamic_cast<Animal *>(creature1);//case 3这个也能正常执行,我就很奇怪了,谁能告诉我?
}
上面代码case1 转换和单继承的一样,case 2 则由于 case 1的作用,可以转换了,case 3就弄不明白了,高手请指点,还是继续看《深度探索C++对象模型》。