dynamic_cast用于具有继承体系的转换中,用于转换指针和引用,通常类必须要有一个虚函数,因为
运行时类的运行信息存储在虚表中,如果没有虚表使用dynamic_cast将会导致编译错误。
dynamic_cast在运行时通过检测底层对象的类型信息,来判断本次转换是否有意义,如果没有意义
dynamic_cast返回空指针(转换指针)或抛出std::bad_cast异常(转换引用)。
dynamic_cast相对于static_cast和reinterpret_cast更加安全,dynamic_cast会执行运行时的动态类型
检查,通过返回值告诉我们本次转换的成功与否,而static_cast和reinterpret_cast可能会出现错误的
类型转换。
另外,dynamic_cast可以和typeid结合实现其他应用,下面的例子中说明了typeid和dynamic_cast结合的使用。
下面通过一个例子具体说明dynamic的使用:
#include <iostream>
using namespace std;
class A{
public:
virtual ~A(){}
};
class B:public A{
public:
void funcB(){
cout << "In B, Not in A!" << endl;
}
};
class C :public A{
public:
void funcC(){
cout << "In C, Not in A!" << endl;
}
};
//测试dynamic_cast的一种应用场景
//访问子类中扩展的父类方法
void dynamic_cast_use(A& a){
if (typeid(a) == typeid(B)){
B& b = dynamic_cast<B&>(a);
b.funcB();
}
if (typeid(a) == typeid(C)){
C& c = dynamic_cast<C&>(a);
c.funcC();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
C *c = new C();
B *b = new B();
A *a = new A();
B *bc = dynamic_cast<B*>(c); //bc == NULL
if (bc == NULL){
cout << "bc == NULL" << endl;
}
else{
cout << "bc != NULL" << endl;
}
B *ba = dynamic_cast<B*>(a); //向下转型,不安全
if(ba == NULL){
cout << "ba == NULL" << endl;
}
else{
cout << "ba != NULL" << endl;
}
A ra;
try{
B& rba = dynamic_cast<B&>(ra);
}
catch (std::bad_cast){
cout << "catch bad_cast exception!" << endl;
}
B Bu;
C Cu;
dynamic_cast_use(Bu); //In B, Not in A!
dynamic_cast_use(Cu); //In C, Not in A!
system("pause");
return 0;
}
程序的运行结果如下: