使用不在基类中的派生方法

时间:2014-11-19 21:00:51

标签: c++ inheritance

我正在做一个Shape类,它允许你获得某个形状的positionX,positionY和区域。派生类是一个圆,它有一个附加的半径​​变量。

class Shape
{
public:
    Shape( double positionX, double positionY );
    virtual double getPositionX() = 0;
    virtual double getPositionY() = 0;
    virtual double area() = 0;

 class Circle : public Shape
{
public:
    Circle( double positionX, double positionY, double radius );
    virtual double getPositionX();
    virtual double getPositionY();
    virtual double area();
    virtual double getRadius();

在我的主要内容中,我有一个Shapes数组,第一个对象是一个新的Circle,我正在调用此Circle上的方法。

int main()
{
    Shape* s[2];

    s[0] = new Circle( 2.0, 3.0, 4.0 );
    cout << s[0]->getPositionX() << endl; // Works fine.
    cout << s[0]->getPositionY() << endl; // Works fine.
    cout << s[0]->getRadius() << endl; // Doesn't work because s is a shape and my shape class has                             
                                       // no getRadius() method.

如何调用getRadius()方法?

2 个答案:

答案 0 :(得分:8)

Ug ......一个好的设计完全避免了这一点。如果你需要得到某个东西的半径,那么它最好能够提供一个半径。如果形状是三角形,你的程序应该做什么?

现在解决这个问题的方法是使用动态转换:

    Circle* circ = dynamic_cast<Circle*>(s[0]);
    if (circ)//check if cast succeeded
    {
       cout << circ->getRadius() << endl;
    }

但这段代码闻起来。一般来说,如果你必须使用dynamic_cast(这很慢而且很混乱),那么你应该重新考虑你的设计。

答案 1 :(得分:-1)

编辑:这个答案很糟糕,并展示了编码错误的一个例子。不要这样做。

你必须把它翻过来。坏C风格演员但工作:

cout << ((Circle*)s[0])->getRadius() << endl;

使用C ++强制转换为更安全。你可以在基类中塑造一个神奇的数字。 int magic_number并为Circle中的每个子类提供一个不同的幻数,它在构造函数中设置。

圈 1 三角形 2 长方形 3

等。然后,在将对象强制转换为子类之前,可以测试对象是否为圆。