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#或Java中的引用都不相同,但是更相似)。
TA贡献1875条经验 获得超5个赞
Animal badDog = Dog();
ad.makeSound();
实例化a Dog并将其按值分配给Animal变量时,将对对象进行切片。基本上,这意味着您要剥离所有Dog-ness badDog并将其加入基类。
为了对基类使用多态,必须使用指针或引用。
- 3 回答
- 0 关注
- 453 浏览
添加回答
举报