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中的引用都不相同,但是更相似)。
TA貢獻1875條經驗 獲得超5個贊
Animal badDog = Dog();
ad.makeSound();
實例化a Dog并將其按值分配給Animal變量時,將對對象進行切片。基本上,這意味著您要剝離所有Dog-ness badDog并將其加入基類。
為了對基類使用多態,必須使用指針或引用。
- 3 回答
- 0 關注
- 486 瀏覽
添加回答
舉報
