3 回答

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超2個(gè)贊
這是一個(gè)稱為“切片”的問題。
Dog()
創(chuàng)建一個(gè)Dog
對(duì)象。如果您要致電Dog().makeSound()
,它將按您期望的那樣打印“樹皮”。
問題是,你是初始化badDog
,這是類型的對(duì)象Animal
,與此Dog
。由于Animal
只能包含Animal
和,而不能包含從派生的任何內(nèi)容Animal
,因此它會(huì)占用的Animal
一部分Dog
并以此進(jìn)行初始化。
的類型badDog
總是Animal
; 它永遠(yuǎn)不可能是別的。
在C ++中獲得多態(tài)行為的唯一方法是使用指針(如您的goodDog
示例所示)或使用引用。
引用(例如Animal&
)可以引用從派生的任何類型的對(duì)象,Animal
而指針(例如Animal*
)可以指向從派生的任何類型的對(duì)象Animal
。Animal
但是,平原永遠(yuǎn)是Animal
,別無其他。
諸如Java和C#之類的某些語言具有引用語義,其中(在大多數(shù)情況下)變量只是對(duì)對(duì)象的引用,因此給定Animal rex;
,rex
實(shí)際上只是對(duì)某些對(duì)象的引用Animal
,rex = new Dog()
而使對(duì)象rex
引用新Dog
對(duì)象。
C ++不能那樣工作:C ++中變量不引用對(duì)象,變量是對(duì)象。如果您rex = Dog()
用C ++講,它會(huì)將一個(gè)新Dog
對(duì)象復(fù)制到中rex
,并且由于rex
實(shí)際上是類型Animal
,因此將對(duì)其進(jìn)行切片,而僅Animal
復(fù)制部分。這些稱為值語義,這是C ++中的默認(rèn)語義。如果要在C ++中使用引用語義,則需要顯式使用引用或指針(這兩個(gè)引用與C#或Java中的引用都不相同,但是更相似)。

TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超5個(gè)贊
Animal badDog = Dog();
ad.makeSound();
實(shí)例化a Dog并將其按值分配給Animal變量時(shí),將對(duì)對(duì)象進(jìn)行切片。基本上,這意味著您要?jiǎng)冸x所有Dog-ness badDog并將其加入基類。
為了對(duì)基類使用多態(tài),必須使用指針或引用。
- 3 回答
- 0 關(guān)注
- 485 瀏覽
添加回答
舉報(bào)