向上和向下转换c++

upcasting and downcasting c++

本文关键字:c++ 转换      更新时间:2023-10-16

我正在摆弄指向基类的指针,我将矩形指针转换为圆形指针,并从矩形调用printradius()函数!有人能解释一下为什么这是允许的吗?谢谢。

#include <iostream>
#include <string>
using namespace std;
class Shape {
};
class Circle: public Shape {
    private:
        double radius;
    public:
        Circle(double r)
        { radius = r;}
    void printradius()
        { cout << "circle's radius is " << radius << endl;}
};
class Rectangle: public Shape {
    private:
        double width, length;
    public:
        Rectangle(double l, double w)
        { length = l; width = w;}
};
int main() {
    Rectangle r( 2.0, 2.0);   // only a rectangle is created
    Shape* s = &r;            // up cast into a shape
    Circle* c = static_cast<Circle*>(s); //down cast into a circle
    c->printradius();
}
输出:

圆的半径是2

你说的"允许"是什么意思?

语言明确地声明这样的static_cast的结果是未定义的,因此在这种情况下它实际上是不"允许的"。为了执行从Shape *Circle *的有效下转换,您必须确保Shape *实际上指向Circle或从Circle派生的东西。否则,行为是未定义的。

至于为什么编译器没有捕获它…编译器不可能捕获依赖于运行时条件的错误。一般情况下,编译器不知道你的s指针实际指向什么。

至于为什么语言甚至提供这样的功能…如果使用得当,它会非常有用。

静态强制转换是"因为我这么说了",换句话说,相信我,程序员,这个东西就是我所说的,在这种情况下是一个圆形指针。当调用printradius()方法时,this指针指向r,而当printradius()碰巧去查找半径时,它会找到第一个double,其值为2.0。以这种方式运行不会导致崩溃或报告错误,但如您所知,这毫无意义。

使用动态强制转换并检查返回值。您将看到null,因为矩形和圆形是不一样的