Este es un problema llamado "rebanar".
Dog()
crea un objeto Dog
. Si llamaras al Dog().makeSound()
, imprimiría "ladrar" como esperabas.
El problema es que está inicializando el badDog
, que es un objeto del tipo Animal
, con este Dog
. Como el Animal
solo puede contener un Animal
y nada derivado de Animal
, toma la parte Animal
del Dog
y se inicializa con eso.
El tipo de badDog
es siempre ; nunca puede ser otra cosa.
La única manera en que puede obtener el comportamiento polimórfico en C++ es usando punteros (como lo ha demostrado con su ejemplo goodDog
) o utilizando referencias.
Una referencia (por ejemplo, Animal&
) puede referirse a un objeto de cualquier tipo derivado de Animal
y un puntero (por ejemplo, Animal*
) puede apuntar a un objeto de cualquier tipo derivado de Animal
. Un simple Animal
, sin embargo, siempre es un Animal
, nada más.
Algunos lenguajes como Java y C# tienen una semántica de referencia, donde las variables son (en la mayoría de los casos) sólo referencias a los objetos, por lo que dado una Animal rex;
, rex
es en realidad una referencia a algún Animal
y rex = new Dog()
hace rex
se refieren a un nuevo Dog
objeto.
C++ no funciona de esa manera: las variables no se refieren a objetos en C++, las variables son objetos. Si dices rex = Dog()
en C++, copia un nuevo objeto Dog
en rex
, y como rex
es en realidad del tipo Animal
, se corta y solo se copian las partes Animal
. Estos se denominan semántica de valores, que son los predeterminados en C++. Si desea semántica de referencia en C++, necesita usar referencias o punteros explícitamente (ninguno de estos es lo mismo que las referencias en C# o Java, pero son más similares).
Creo que tiene algunos errores de nomenclatura para sus variables. – aioobe
El código ni siquiera se compila como está. Y 'void main()' ??? Ew ... –
No puedo entender por qué alguien rechazó esta pregunta, no es "poco clara" ni "no útil". +1 para negar el downvote. – casablanca