顾名思义,与静态类型转换相反,动态类型转换在运行阶段(即应用程序运行时)执行类型转换。
可检查 dynamic_cast 操作的结果,以判断类型转换是否成功。使用 dynamic_cast 运算符的典型语法如下:
destination_type* Dest = dynamic_cast<class_type*>(Source);
if(Dest) // Check for success of the casting operation
Dest->CallFunc ();
例如:
Base* objBase = new Derived();
// Perform a downcast
Derived* objDer = dynamic_cast<Derived*>(objBase);
if(objDer) // Check for success of the cast
objDer->CallDerivedFunction ();
如上述代码所示,给定一个指向基类对象的指针,程序员可使用 dynamic_cast 进行类型转换,并在使用指针前检查指针指向的目标对象
的类型。在上述示例代码中,目标对象的类型显然是 Derived,因此这些代码只有演示价值。然而,情况并非总是如此,例如,将
Derived*
传递给接受 Base*
参数的函数时。该函数可使用 dynamic_cast 判断基类指针指向的对象的类型,再执行该类型特有的操作。总之,可使用 dynamic_cast 在运行阶段判断类型,并在安全时使用转换后的指针。
虚基类(或称抽象类)可以使用dynamic_cast,但是,非虚基类不可以。
在dynamic_cast被设计之前,C++无法实现从一个虚基类到派生类的强制转换。dynamic_cast就是为解决虚基类到派生类的转换而设计的。
示例代码:
子类—>父类(虚基类)
#include
#include
//美术家
class Artist {
public:
virtual void draw() {printf("Artist draw\n");}
};
//音乐家
class Musician {
public:
};
//教师
class Teacher {
public:
virtual void teachStu() {printf("Teacher teachStu\n");}
};
//即是美术,又是音乐家,又是教师的人
class People: public virtual Artist,public virtual Musician,public Teacher {
public:
};
void test1() {
People *p1 = new People();
p1->draw();
p1->teachStu();
printf("\ndynamic_cast test:\n");
Artist *a1 = dynamic_cast<Artist*>(p1);
//Artist *a1 = p1; //向上转换,C++总是能够正确识别。即将派生类的指针赋值给基类指针。
a1->draw(); //success: 打印Artist draw
//a1->teachStu(); //error: no member named 'teachStu' in 'Artist'
}
int main() {
test1();
return 0;
}
说明:
1)继承关系:People 继承自Artist,Musician,Teacher三个类;
2)语意:Artist美术家,Musician音乐家,Teacher教师。
People类:定义一个特殊的People类,它的特点是:既是美术家,又是音乐家,也是教师。
上面的代码,运行结果如下:
Artist draw
Teacher teachStu
dynamic_cast test:
Artist draw
分析:
下面两条语句均正确,都能由子类People转化为父类Artist,并且调用父类Artist的成员函数成功。
Artist *a1 = dynamic_cast(p1); 等价于
Artist *a1 = p1;
a1->draw(); //success: 打印people teachStu
可见,向上转换,无论是否用dynamic_cast,C++总是能够正确识别,即将派生类的指针赋值给基类指针。
父类(虚基类)—>子类,采用虚继承的方式:
对于上面的类,再看如下代码:
void test1() {
People *p1 = new People();
printf("\ndynamic_cast test:\n");
Artist *a1 = p1; //success
//People *p2 = (People*)a1; //error: cannot cast 'Artist *' to 'People *' via virtual base 'Artist'
People *p3 = dynamic_cast<People*>(a1);//success:加了dynamic_cast,进行强转
}
分析:
1) //People p2 = (People)a1; //error: cannot cast ‘Artist *’ to 'People ’ via virtual base ‘Artist’,
明确说明,无法直接用(T)b的形式去进行由父类指针到派生类指针的转换;
2) People p3 = dynamic_cast
由父类指针到派生类指针的转换通过dynamic_cast完成。
该文章会更新,欢迎大家批评指正。
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器