【问题标题】:Using derived methods that aren't in the base class使用不在基类中的派生方法
【发布时间】:2015-01-17 13:32:01
【问题描述】:

我正在做一个 Shape 类,它允许您获取某个形状的位置 X、位置 Y 和区域。派生类是一个Circle,它增加了一个半径变量。

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();

在我的 main 中,我有一个 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() 方法?

【问题讨论】:

  • 如果都是圆圈,为什么不创建一个圆圈数组呢?如果数组可以包含任何形状,那么在非圆上调用 getRadius 应该做什么?要回答您的问题,dynamic_cast&lt;Circle&amp;&gt;(*s[0]).getRadius()

标签: c++ inheritance


【解决方案1】:

Ug...一个好的设计可以完全避免这种情况。如果您需要获取某物的半径,那么最好是可以提供半径的东西。如果形状是三角形,你的程序应该怎么做?

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

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

但是这段代码有异味。一般来说,如果您必须使用 dynamic_cast(既慢又混乱),那么您应该重新考虑您的设计。

【讨论】:

    【解决方案2】:

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

    你必须向上转型。糟糕的 C 风格转换但有效:

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

    使用 C++ 强制转换更安全。您可以在基类中塑造一个幻数。 int magic_number 并给每个像 Circle 这样的子类一个不同的幻数,该幻数在构造函数中设置。

    圆 1 三角形 2 长方形 3

    等等。然后,您可以在将对象投射到其子类之前测试它是否为圆形。

    【讨论】:

    • 既然知道 C++ 有更安全的转换,为什么还要推荐糟糕的 C 转换?我不明白幻数建议的用途。
    • 我从 C 开始,习惯了这种糟糕的风格。你的例子更好。我将把这个答案留在这里,让人们知道如何不解决这个问题(幻数 + c 样式转换)。至少这是一个不好的例子。
    猜你喜欢
    • 2018-10-12
    • 2019-07-25
    • 2016-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    相关资源
    最近更新 更多