C++的类型转换运算符:dynamic_cast

C++的类型转换运算符:dynamic_cast

顾名思义,与静态类型转换相反,动态类型转换在运行阶段(即应用程序运行时)执行类型转换。
可检查 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>(a1);//success:加了dynamic_cast,进行强转。

由父类指针到派生类指针的转换通过dynamic_cast完成。

该文章会更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器

你可能感兴趣的:(CC++编程要点,c++)