向上转发和向下转换c ++

时间:2015-07-30 19:16:07

标签: c++ function virtual upcasting

我正在玩指向基类的指针,我将一个矩形指针转换为圆形指针,并从矩形中调用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

  

2 个答案:

答案 0 :(得分:3)

你是什么意思&#34;允许&#34;?

该语言明确指出此类static_cast的结果未定义,因此它并非真正允许&#34;在这种情况下。要从Shape *Circle *执行有效的向下转发,您必须确保Shape *实际指向Circle或从Circle派生的内容。否则,行为未定义。

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

至于为什么语言甚至提供这样的功能......它提供它,因为当它正确使用它时它会非常有用。

答案 1 :(得分:0)

静态演员是“因为我这么说。”,换句话说,相信我,程序员,事情就是我所说的,在这种情况下是一个圆圈指针。调用printradius()方法时,this指针用于r,当printradius()发生deref寻找半径时,它会发现第一个双精度值,其值为2.0。运行这种方式没有崩溃或报告错误,但正如您所知,这没有任何意义。

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