C ++中的继承和指针

时间:2017-11-08 16:17:06

标签: c++ inheritance polymorphism

我有这个代码示例,我想了解它为什么会这样做。这是一篇介绍C ++课程中过去的试卷的问题。我现在正在攻读考试,并试图巩固我对班级继承的理解。

#include <iostream>
using namespace std;

class Bird {
  public:
    virtual void noise() { cout << "mumble" << endl; }
    void move() { noise(); cout << "fly" << endl; }
};

class Canary: public Bird {
  public:
    void noise() { cout << "chirp" << endl; }
    void move() { noise(); cout << "flap" << endl; }
};

class Tweety: public Canary {
  public:
    void noise() { cout << "tweet" << endl; }
    void move() { noise(); cout << "run" << endl; }
};

int main() {
    Canary *yellow = new Tweety();
    yellow->noise();
    yellow->move();
    return 0;
}

我已运行此代码,输出为:

鸣叫 鸣叫 襟翼

这意味着它正在调用noise()的 Tweety 实现,但它正在调用move()的 Canary 实现。我很困惑。我理解多态的想法,而noise()是虚拟的,因此它调用Tweety版本是有道理的,因为* yellow是指向Tweety的指针。但为什么它称为Canary版本的move()?

我认为令我感到困惑的是这条线:

Canary *yellow = new Tweety();

这表示* yellow是一个Canary指针,指向Tweety对象。我对此很好,因为我得到指向基类的指针可以指向派生类。但*黄色指向Tweety,那为什么不使用Tweety的移动()?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

noise是虚拟的,因此在您调用它时会动态调度到Tweety实现。

move非虚拟,因此要调用的版本是在编译时根据您调度通过的类型决定的。由于yellowCanary,编译器会解析在编译时调用的内容,并在move中显式调用Canary方法。

答案 1 :(得分:1)

move()也应该是virtual,否则会调用指针类型的版本。

答案 2 :(得分:0)

肖恩和亚历克斯是现场。

以下是一些有助于理解不同场景的呼叫案例。

#include <iostream>
using namespace std;

class Bird {
  public:
    virtual void noise() { cout << "mumble" << endl; }
    void move() { noise(); cout << "fly" << endl; }

    void noise2() { cout << "mumble2" << endl; }
    virtual void move2() { noise2(); cout << "fly2" << endl; }
};

class Canary: public Bird {
  public:
    void noise() { cout << "chirp" << endl; }
    void move() { noise(); cout << "flap" << endl; }

    void noise2() { cout << "chirp2" << endl; }
    void move2() { noise2(); cout << "flap2" << endl; }
};

class Tweety: public Canary {
  public:
    void noise() { cout << "tweet" << endl; }
    void move() { noise(); cout << "run" << endl; }

    void noise2() { cout << "tweet2" << endl; }
    void move2() { noise2(); cout << "run2" << endl; }
};

int main() {
    Canary *yellow = new Tweety();
    yellow->noise();
    yellow->move();
    yellow->noise2();
    yellow->move2();
    return 0;
}

/* OUTPUT:
tweet    <- virtual dispatch
tweet    <- virtual dispatch, via Bird::move()
flap     <- direct call
chirp2   <- direct call
tweet2   <- direct call, from Tweety::move2()
run2     <- virtual dispatch
*/