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 瀏覽
添加回答
舉報