簡體   English   中英

C ++中的繼承和指針

[英]Inheritance and pointers in C++

我有這個代碼示例,我想了解為什么它的行為方式如此。 這是過去的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對象。 我可以接受,因為我知道指向基類的指針可以指向派生類。 但是* yellow指向Tweety,那么為什么不使用Tweety的move()?

在此先感謝您的幫助。

noise是虛擬的,因此在調用它時會動態地將其分派到Tweety實現。

move不是虛擬的,因此要調用的版本是在編譯時根據要通過其分派調用的類型確定的。 由於yellowCanary因此編譯器會解析在編譯時將要調用的內容,並將在Canary顯式調用move方法。

move()也應該是virtual否則將調用指針類型的版本。

肖恩和亞歷克斯都在場。

這是一些更多的用例,應有助於理解不同的情況。

#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
*/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM