C++学习笔记(14) static_cast 与 dynamic_cast

dynamic_cast运算符能够在运行时将一个对象强制转换成其实际类型:

实际应用场景:在C++学习笔记(13)中,在main.cpp里面定义了displayGeometric()函数,

void displayGeometric(const Geometric& g)
{
    cout << g.toString() << endl;	
} 

假设现在需要对这个函数进行修改:

函数参数类型不变,当参数时rectangle类型的对象时,输出width和height, 当参数是circle类型的对象时,输出半径 。

首先介绍一种错误的实现方法

void displayGeometric(const Geometric& g)
{
        cout << "The radius is " << g.getRadius() << endl;
	
	cout << "The width is " << g.getWidth() << endl;
	cout << "The height is " << g.getHeight() << endl;	
} 

很明显,这种方法是无法通过编译的!

在前面的学习中,知道static_cast能够对变量进行强制类型转换(静态转换)。能否通过static_cast实现呢?

void displayGeometric(const Geometric& g)
{
    Geometric* p = &g;

    cout << "The radius is " << static_cast<Circle*>(p)->getRadius() << endl;
	
    cout << "The width is " << static_cast<Rectangle*>(p)->getWidth() << endl;
    cout << "The height is " << static_cast<Rectangle*>(p)->getHeight() << endl;	
} 

这样会存在函数 displayGeometric() 可能会将circle错误的转化为rectangle而调用getWidth()方法。所以任然是错误的,因为static_cast()不能对转换成功的结果进行检查,而我们的要求是,在调用getRadius()之前必须确保对象是一个circle.

dynamic_cast与static_cast的功能类似,但是,dynamic_cast在运行时进行检查从而保证转换的成功进行。转换失败会返回NULL. 所以用dynamic_cast可以实现上面要求的功能

void displayGeometric(const Geometric& g)
{
	Geometric* p = &g;
	Circle* p1 = dynamic_cast<Circle*>(p);
	Rectangle* p2 = dynamic_cast<Rectangle*>(p);
	if(p1 != NULL)  // Circle类性转换成功
	{
		cout << "The radius is " << p1->getRadius() << endl;
	} 
    
        if(p2 != NULL)  // Rectangle转换成功
	{
	    cout << "The width is " << p2->getWidth() << endl;
    	cout << "The height is " << p2->getHeight() << endl;	
	} 	
} 

注:

dynamic_cast只能在多态类型的指针或者引用上使用,也就是说该类型必须包含虚函数,dynamic_cast可以在运行时检查强制转换是否成功。static_cast则在编译的时候起作用。

猜你喜欢

转载自blog.csdn.net/zj1131190425/article/details/84960428