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;
}

 

运行结果:

 

 这样一来就可以避免强行转换的错误。

 

posted @ 2020-04-30 13:21  川尘  阅读(452)  评论(0编辑  收藏  举报
`