亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

學習C ++:多態性和切片

學習C ++:多態性和切片

C++
www說 2019-09-24 16:32:54
考慮以下示例:#include <iostream>using namespace std;class Animal{public:    virtual void makeSound() {cout << "rawr" << endl;}};class Dog : public Animal{public:    virtual void makeSound() {cout << "bark" << endl;}};int main(){    Animal animal;    animal.makeSound();    Dog dog;    dog.makeSound();    Animal badDog = Dog();    badDog.makeSound();    Animal* goodDog = new Dog();    goodDog->makeSound();}輸出為:rawrbarkrawrbark但是我認為輸出肯定應該是“ raw kark bark bark”。badDog怎么了?更新:您可能對我的另一個問題感興趣。
查看完整描述

3 回答

?
一只斗牛犬

TA貢獻1784條經驗 獲得超2個贊

這是一個稱為“切片”的問題。

Dog()創建一個Dog對象。如果您要致電Dog().makeSound(),它將按您期望的那樣打印“樹皮”。

問題是,你是初始化badDog,這是類型的對象Animal,與此Dog。由于Animal只能包含Animal和,而不能包含從派生的任何內容Animal,因此它會占用的Animal一部分Dog并以此進行初始化。

的類型badDog總是Animal; 它永遠不可能是別的。

在C ++中獲得多態行為的唯一方法是使用指針(如您的goodDog示例所示)或使用引用。

引用(例如Animal&)可以引用從派生的任何類型的對象,Animal而指針(例如Animal*)可以指向從派生的任何類型的對象Animal。Animal但是,平原永遠是Animal,別無其他。

諸如Java和C#之類的某些語言具有引用語義,其中(在大多數情況下)變量只是對對象的引用,因此給定Animal rex;rex實際上只是對某些對象的引用Animal,rex = new Dog()而使對象rex引用新Dog對象。

C ++不能那樣工作:C ++中變量不引用對象,變量是對象。如果您rex = Dog()用C ++講,它會將一個新Dog對象復制到中rex,并且由于rex實際上是類型Animal,因此將對其進行切片,而僅Animal復制部分。這些稱為值語義,這是C ++中的默認語義。如果要在C ++中使用引用語義,則需要顯式使用引用或指針(這兩個引用與C?;騄ava中的引用都不相同,但是更相似)。


查看完整回答
反對 回復 2019-09-24
?
慕田峪4524236

TA貢獻1875條經驗 獲得超5個贊

Animal badDog = Dog();

    ad.makeSound();

實例化a Dog并將其按值分配給Animal變量時,將對對象進行切片。基本上,這意味著您要剝離所有Dog-ness badDog并將其加入基類。


為了對基類使用多態,必須使用指針或引用。


查看完整回答
反對 回復 2019-09-24
  • 3 回答
  • 0 關注
  • 486 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號