[英]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
不是虛擬的,因此要調用的版本是在編譯時根據要通過其分派調用的類型確定的。 由於yellow
是Canary
因此編譯器會解析在編譯時將要調用的內容,並將在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.