C++类型转换:static_cast和dynamic_cast
如果我们想在displayGeometricObject函数中显示更多的信息(详见C++泛型程序设计和多态)。假如是圆,那么显示其半径;假如是一个矩形,则显示其长和宽。
在这里,由于要进行类型转换,所以函数签名改为displayGeometricObject(GeometricObject& g)。
由于我们传入的参数是一个GeometricObject类的对象,所以它并不能直接显示半径或长和宽,我们需要对g进行类型转换。首先尝试静态类型转换static_cast
#include <iostream> #include "GeometricObject.h" #include "Circle.h" #include "Rectangle.h" using namespace std; void displayGeometricObject(GeometricObject& g) { //在控制台打印对象g的描述信息 cout << g.toString() << endl; cout << "半径为:" << static_cast<Circle*>(&g)->getRadius() << endl; cout << "长为:" << static_cast<Rectangle*>(&g)->getHeight() << endl; cout << "宽为:" << static_cast<Rectangle*>(&g)->getWidth() << endl; } int main() { Circle c; Rectangle r; displayGeometricObject(c); displayGeometricObject(r); return 0; }
很明显静态类型转换存在错误,因为我们无法判断输入的是圆还是矩形,我们甚至可以把圆强行转换为矩形,那么就会出现错误:
(其实使用静态转换也可以通过判断g.toString返回的字符串而选择转换的方式,但是更加推荐使用动态转换)
因此我们要使用动态转换的方式dynamic_cast,在动态转换时,把Circle类转换为Rectangle类会转换失败,返回一个null(空值)
#include <iostream> #include "GeometricObject.h" #include "Circle.h" #include "Rectangle.h" using namespace std; void displayGeometricObject(GeometricObject& g) { //在控制台打印对象g的描述信息 cout << g.toString() << endl; Circle* p1 = dynamic_cast<Circle*>(&g); Rectangle* p2 = dynamic_cast<Rectangle*>(&g); if(p1 != NULL) { cout << "半径为:" << static_cast<Circle*>(&g)->getRadius() << endl; } if(p2 != NULL) { cout << "长为:" << static_cast<Rectangle*>(&g)->getHeight() << endl; cout << "宽为:" << static_cast<Rectangle*>(&g)->getWidth() << endl; } } int main() { Circle c; Rectangle r; displayGeometricObject(c); displayGeometricObject(r); return 0; }
运行结果:
这样一来就可以避免强行转换的错误。